我在为树中的节点动态分配字符串时遇到了一些问题。我在下面包含了我的节点结构以供引用。
struct node
{
char *string;
struct node *left;
struct node *right;
};
typedef struct node node;
我应该从文本文件中读取单词,然后将这些单词存储到树中。我能够毫无问题地存储已定义的 char 数组,例如 char string[20],但不能存储应该动态分配的字符串。
我只会发布我用来读取文件并尝试创建动态分配数组的代码。我已经创建了文件指针并检查它不是 NULL。每次我尝试运行该程序时,它都会崩溃,我是否需要尝试逐个字符地阅读单词?
//IN MAIN
node *p, *root ;
int i;
int u;
root = NULL;
char input[100];
while(fscanf(fp, "%s", &input) != EOF)
{
//Create the node to insert into the tree
p = (node *)malloc(sizeof(node));
p->left = p->right = NULL;
int p = strlen(input); //get the length of the read string
char *temp = (char*) malloc(sizeof(char)*p);
//malloc a dynamic string of only the length needed
strcpy(local, input);
strcpy(p->word,local);
insert(&root, p);
}
完全清楚,我只需要有关我的代码逻辑的建议,并且只希望有人帮助我指明正确的方向。
最佳答案
您正在通过
调用许多未定义的行为- 将指向具有错误类型的对象的指针传递给
scanf()
。即在fscanf(ifp, "%s", &input)
中,char(*)[100]
被传递到预期char*
的地方 - 在
strcpy(local, input);
中存储终止空字符时访问超出范围的已分配缓冲区
- 使用通过
malloc()
分配的缓冲区值,但未在strcpy(curr->word,local);
中初始化
你的代码应该是这样的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct node_t {
struct node_t* left, *right;
int count;
char* word;
} node;
void insert(node ** tree, node * item);
int main(void) {
FILE* ifp = stdin;
node * curr, * root;
int i;
int u;
root = NULL;
char input[100];
/* you should specify the maximum length to read in order to avoid buffer overrun */
while(fscanf(ifp, "%99s", input) != EOF)
{
//Create the node to insert into the tree
curr = malloc(sizeof(node));
if(curr == NULL) /* add error check */
{
perror("malloc 1");
return 1;
}
curr->left = curr->right = NULL;
curr->count = 1;
int p = strlen(input); //get the length of the read string
char *local = malloc(sizeof(char)*(p + 1)); /* make room for terminating null-character */
if (local == NULL) /* add error check again */
{
perror("malloc 2");
return 1;
}
//malloc a dynamic string of only the length needed
//To lowercase, so Job and job is considered the same word
/* using strlen() in loop condition is not a good idea.
* you have already calculated it, so use it. */
for(u = 0; u < p; u++)
{
/* cast to unsigned char in order to avoid undefined behavior
* for passing out-of-range value */
input[u] = tolower((unsigned char)input[u]);
}
strcpy(local, input);
curr->word = local; /* do not use strcpy, just assign */
insert(&root, curr);
}
/* code to free what is allocated will be here */
return 0;
}
//Separate insert function
void insert(node ** tree, node * item)
{
if(!(*tree))
{
*tree = item;
return;
}
if(strcmp(item->word,(*tree)->word) < 0)
insert(&(*tree)->left, item);
else if(strcmp(item->word,(*tree)->word) > 0)
insert(&(*tree)->right, item);
/* note: memory leak may occur if the word read is same as what is previously read */
}
关于从 C 文件创建动态分配的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35857535/