下面是一个小型C应用程序。它会要求你输入一个词。它停止询问何时获得了四个独特的单词。但是在下面显示的形式中,在取消注释相关行之前它将无法正常运行。
#include <stdio.h>
#include <string.h>
#define WORDS_COUNT 4
int main()
{
char* words[WORDS_COUNT];
int words_added = 0;
while (words_added<WORDS_COUNT)
{
puts ("\n-------enter a word-------");
char response[250];
scanf("%s", response);
int i;
int duplicate_flag = 0;
for (i=0; i < words_added; i++)
{
if (strcmp(words[i], response) == 0)
{
duplicate_flag = 1;
break;
};
};
if (duplicate_flag == 0)
{
//char tmp[250];
//strcpy(tmp, response);
words[words_added] = response; //words[words_added] = tmp;
puts("that's new!");
words_added ++;
} else {
puts("you've said that already...");
};
};
return 0;
};
您可以看到的主要区别在于words[words_added] = response
和words[words_added] = tmp
。
为什么tmp
变量有效而不是response
?
我猜测response
每次迭代都会有完全相同的地址,tmp
每次迭代都会获得一个新地址。但为什么?然而他们都被宣布在同一个循环???
答案 0 :(得分:2)
分配words[words_added] = response
时,您将response
的地址(不是内容)复制到数组中。因此,在原始格式中,您的代码应该将第二个单词和每个后续单词视为重复。当您使用tmp
代码时,代码会将每个新的response
与存储在tmp
的{每个位置}中的words[]
进行比较,然后将其复制到tmp
如果它不重复。
因此,我怀疑您的代码会检测到立即跟随原始文件的副本,而不是之后发生2个或更多单词的副本。
words
数组包含4个指针,但没有为这些指针分配内存。
您需要为words
数组的每个元素分配内存,然后将每个字符串复制到其中:
if (duplicate_flag == 0)
{
words[words_added++] = strdup(response); // allocates mem and copies the string
puts("that's new!");
} else {
...
}
然后确保free
程序结束时的内存:
for (i = 0; i < words_added; ++i) {
free(words[i]);
}
答案 1 :(得分:1)
你做错了 - 你指的是一系列指针 - words[words_added]
- 在每次迭代时变化的变量 - response
在strcpy之前,您需要在每次迭代时为words[words_added]
分配存储空间:
strcpy(words[words_added], response);
P.S。关闭大括号}