C中的字符串数组,行为异常

时间:2018-10-07 19:51:41

标签: c arrays string

我正在尝试解决关于密码游戏的难题。
这是简单的代码:

#include <stdio.h>    
int main(void) {
    char *hashTable[3];
    for (int i = 0; i < 3; i++) 
    {
        char EXT[101]; 
        char MT[501];
        scanf("%s%s", EXT, MT); fgetc(stdin);
        hashTable[i]= MT;
    }
    printf("%s\n",hashTable[0]);
    printf("%s\n",hashTable[1]);
    printf("%s\n",hashTable[2]);
}

例如,如果我输入:a a \ n b b \ n c c \ n
输出将是:“ c c c”而不是“ a b c”。为什么最后一个值“ c”会覆盖hashTable [0]和hashTable [1]。 相反,使用以下代码,我收到了正确的输出:

#include <stdio.h>    
int main(void) {
    char *hashTable[3];
    char *hashTable2[3];
    hashTable2[0]="a";
    hashTable2[1]="b";
    hashTable2[2]="c";
    for (int i = 0; i < 3; i++) 
    {
        hashTable[i]= hashTable2[i];
    }
    printf("%s ",hashTable[0]);
    printf("%s ",hashTable[1]);
    printf("%s ",hashTable[2]);
}

3 个答案:

答案 0 :(得分:0)

首先,EXTMTfor循环作用域中是本地的,并且在该作用域之外不存在。这是一个UB。

其次,您将相同的数组地址分配给char *数组的所有元素。当您退出循环时,该地址不再有效。

您需要为所有元素分配内存:

for (int i = 0; i < 3; i++) 
{
    hashTable[i]= malloc( /*some size*/);
    if(hashTable[i])
        scanf("%s", hashTable[i]); /* just an example */
}

答案 1 :(得分:0)

数组config.phpEXT在包含块MT的局部;它们在终止的for处不复存在。

在该区块内,您将其地址放置在}中。

当您尝试打印其内容时(请记住此时阵列已不复存在),您将调用未定义的行为

答案 2 :(得分:-1)

您将指针分配到相同的存储区域,因此将显示最后输入的值。

MT是保留的501字节内存,您将用户输入的值放在此处,然后将MT的地址分配给hashTable [i]。然后,您将一个新值放入相同的501字节中,以覆盖前一个值。

例如,假设MT [501]的起始物理地址为1000,那么每个hashTable元素将等于1000,并指向相同的内存。这就是为什么您要打印相同的值。

此外,由于您将变量声明为“ auto”,因此它将在堆栈中分配。块执行结束后,将调整堆栈指针,因此该内存可在下一次分配时重用。在块的结尾和打印之间没有任何其他分配,这是因为它没有被覆盖。否则,它将被下一次内存分配覆盖。