【发布时间】:2017-08-28 11:14:38
【问题描述】:
#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->children[a[0]-97] 无法访问。
例如,我先添加 abc,然后添加 acd。这将出现段错误。
另外,我相信我的函数中存在一些内存泄漏。我在 valgrind 中检查了我的代码。它说 free() 在 free(s) 处无效
对不起,我应该在开头提到这一点。 a 假设由小写字母组成。而我目前所有的测试输入,只考虑添加和查找操作。
【问题讨论】:
-
如果 strlen(a) 恰好是
s = trim(s);会做一些奇怪的事情。 -
if (s != NULL)应该在fgets(s, MAX_BUF_SIZE, stdin);之前检查 -
顺便说一句,每次你创建一个
newNode然后你会在添加函数结束时释放,所以第二次内存不存在..... -
s = trim(s);后面不能是free(s);。因为它与malloc的返回值不同。 -
free必须应用。例如,您可以执行以下操作。char* buff = malloc(MAX_BUF_SIZE);while(t != 0){ char* s = buff;... } free(buff);或char buff[MAX_BUF_SIZE];而不是char* buff = malloc(MAX_BUF_SIZE);Alosfree(contacts);移动到 while-loop 之后。让我们释放整个树。
标签: c memory memory-leaks segmentation-fault