我有一个函数可以创建结构的链表。
struct words {
char * word;
words next;
};
typedef struct words s_words;
typedef words * Words;
我得到了一个使用代码创建链接列表的函数
Words w = NULL; // start of the list
Words t; // temp node
if (t = (Words) malloc(sizeof(s_words))) {
t->word = a_string_created;
t->next = w;
w = t; // Adding at start of the list
}
如果我做了一个printf("%s",t->word)
和printf("%s",a_string_created)
,我得到了相同的值。
我的问题是当我试图从另一个函数检索word
时。
int readWords(Words list, char * wordRead) {
if (list != NULL) {
//strcpy(wordRead,list->word);
wordRead = list->word;
return 1;
}
else {
return 0;
}
}
我无法获得readWords
中的值。里面的printf("%s",list->word)
给了我一个奇怪的特征。从调用方函数
char rw[11]; //I've try char* rw too
readWords(aList,rw);
printf("%s",rw)
不打印任何内容。
我被这个问题困扰了好几个小时。肯定有一些事情我看不懂。
编辑:
我通过用strcpy(t->word, a_string_created);
替换t->word = a_string_created;
解决了部分问题。现在,在我的printfs上,我打印字符串值。但某些值的值略有变化,例如:test变为uest!!
回答
将t->word = a_string_created;
更改为t->word = strdup(a_string_created);
任何人都可以帮我解释我哪里错了,为什么错了?
问题的发生是因为readWords
滥用了缓冲区:readWords
没有将字符串从列表复制到缓冲区中,而是将其指定为指针。由于rw
是按值传递的,因此缓冲区的内容保持未初始化状态,导致由于未定义的行为而导致无效的打印输出。
有几种方法可以解决这个问题:
- 使用
strcpy
将list->words
的内容复制到wordRead
缓冲区中,或者 - 更改
readWords
以获取指向wordRead
的指针的指针,并将其分配给list->words
strcpy
方法不太安全,除非您也考虑缓冲区的大小。指针对指针的方法如下所示:
int readWords(Words list, char **wordRead) {
if (list != NULL) {
*wordRead = list->word;
return 1;
} else {
return 0;
}
}
通话内容如下:
char *rw;
if (readWords(aList, &rw)) {
printf("%s", rw)
}
您正在为struct
分配内存,但未能为字符串分配内存。
不仅如此,您的函数还尝试将char *
变量wordRead
设置为存储字符串的开头。但它从不在函数之外返回这个值——这似乎是函数的意图。你的第二个函数应该是:
int readWords(Words list, char **wordRead) {
if (list != NULL) {
*wordRead = list->word;
return 1;
} else {
return 0;
}
}
问题是您需要为wordRead传递一个双指针。按照您的方法,您只需修改一个局部值。
因此,正确的原型是int readWords(Words list, char ** wordRead)
。
在您的struct
中,您需要为char*
进行分配。如果没有为char数据分配空间,则指针已经指向垃圾。
其次,strcpy
并不总是安全的,除非您明确检查要复制的数据的大小,并确保最后字符串中有一个' '
。CCD_ 29比CCD_。