c while while循环将局部变量视为全局,为什么?

时间:2012-02-21 21:53:07

标签: c memory while-loop

下面是一个小型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] = responsewords[words_added] = tmp

为什么tmp变量有效而不是response

我猜测response每次迭代都会有完全相同的地址,tmp每次迭代都会获得一个新地址。但为什么?然而他们都被宣布在同一个循环???

2 个答案:

答案 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。关闭大括号}

后不要放置分号