seg fault:无法访问地址处的内存

时间:2017-04-03 14:21:12

标签: c memory memory-leaks segmentation-fault

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

#define ALPHABET_LENGTH    26
#define OPERATION_BUF_SIZE  5
#define NAME_BUF_SIZE      22
#define MAX_BUF_SIZE       27

#ifndef NULL 
#define NULL ((void*)0) 
#endif

/* Basic trie node -- also, keep track of number of nodes below this one. */
typedef struct node {
    int num_children;
    struct node *children[ALPHABET_LENGTH];
} trie_node;

trie_node* init(trie_node* a) {
    a->num_children = 0;
    for (int i = 0; i < ALPHABET_LENGTH; ++i)
    {
        a->children[i] = NULL;
    }
    return a;
}

char* trim(char* a){
    if (a[0] == 'a')
    {
        a += 4;
    }else{
        a += 5;
    }
    return a;
}

void add(char* a, trie_node* node){//need to make sure a is not NULL at beginning
    trie_node* newNode = malloc(sizeof(struct node));
    newNode = init(newNode);
    int i;
    if ((a != NULL && a[0] !='\n') && node->children[a[0] - 97] == NULL)
    {
        node->num_children++;
        //initialize the children array
        for (i = 0; i < ALPHABET_LENGTH; i++)
        {
            if (newNode->children[i] != NULL)
            {
                newNode->children[i] = NULL;
            }
        }
        newNode -> num_children = 0;
        node->children[a[0] - 97] = newNode;
        a++;
        add(a, newNode);
    }
    else if ((a != NULL && a[0] !='\n') && node->children[a[0] - 97] != NULL){
        a++;
        node->num_children++;
        add(a, node->children[a[0] - 97]);
    } else{//a == NULL, which means end of the add procedure
        return;
    }
    free(newNode);
}

int main()
{
    int t,total,remain,temp;
    scanf("%d\n", &t);
    total = t;
    trie_node* contacts = malloc(sizeof(struct node));
    contacts = init(contacts);
    while(t != 0){
        char* s = malloc(MAX_BUF_SIZE); //char array to store the input
        t--;
        remain = total - t;
        fgets(s, MAX_BUF_SIZE, stdin);
        if (s[0] == 'a')
        {
            s = trim(s);
            //do add operation
            if (s != NULL)
            {//make sure there is something to add
                add(s, contacts);
            }

        }
        else{
            printf("No such operation found at line %d. (Only add or find is allowed)\n", remain);
        }
        free(contacts);
        free(s);//memory leak problem
    }

    //if operation is not add or find, will be an error.
    return 0;
}

每次我的程序进入add函数的第二种情况时,这是else if语句,它会断言说无法访问node-&gt; children [a [0] -97]。 例如,我确实添加了abc然后添加了acd。这将得到一个段错误。 另外,我相信我的功能有一些内存泄漏。我在valgrind中检查我的代码。它表示free(s)无效free()。​​

对不起,我应该在开始时提到这一点。假设由小写字母组成。我现在所有的测试输入,只考虑添加和查找操作。

1 个答案:

答案 0 :(得分:0)

首先,感谢所有回复我问题的人。我的函数中的真正问题是我在使用[0]访问节点位置之前修改了一个
以下是我解决问题的方法:

void add(char* a, trie_node* node){//need to make sure a is not NULL at beginning
    int i,temp;
    if ((a != NULL && a[0] !='\n') && node->children[a[0] - 97] == NULL)
    {
        node->num_children++;
        //initialize the children array
        trie_node* newNode = malloc(sizeof(struct node));
        newNode = init(newNode);
        node->children[a[0] - 97] = newNode;
        a++;
        add(a, newNode);
    }
    else if ((a != NULL && a[0] !='\n') && node->children[a[0] - 97] != NULL){
        node->num_children++;
        temp = a[0];
        a++;
        add(a, node->children[temp - 97]);//line 56
    } else{//a == NULL, which means end of the add procedure
        return;
    }
}

我添加一个int temp来存储[0]的值,然后执行++。

在我这样做之前,如果我&#34;添加abc&#34;然后&#34;在第二个循环中添加acd&#34;,在第56行,添加函数将获得a的值&#34; cd \ n&#34;,以及node-&gt; children的值[a [ 0] -97]其中a [0]现在是c而不是a。

现在一切都是固定的。谢谢大家!