我正在学习C。我遇到了字符串数组。我对以下代码感到困惑。我正在期待一种输出。但是,由于读取访问冲突,导致获得完全不同的输出或程序崩溃。

我已在Visual Studio 2017上使用_CRT_SECURE_NO_WARNINGS运行此代码

// case 1

char* name[2];
//name[0] = (char*)malloc(sizeof(char*) * 10);
//name[1] = (char*)malloc(sizeof(char*) * 10);
name[0] = "john";
name[1] = 'doe';
printf("%s\n", name[0]); // prints john
//printf("%s\n", name[1]); // gives read access violation exception, why??? even with dynamically allocated memory

// case 2

char* name2[2] = { "emma", "olsson" };
printf("%s\n", name2[0]); // prints emma
printf("%s\n", name2[1]); // prints olsson, why no error???

// case 3

for (int i = 0; i < 2; i++)
{
    name[i] = name2[i];
}
printf("%s\n", name[0]); // prints emma
printf("%s\n", name[1]); // prints olsson, why no error???

// case 4

char inputName[10];
int i = 0;
while (i < 2)
{
fgets(inputName, sizeof(inputName), stdin); // first input: Max   second input: Payne
char* pos = strchr(inputName, '\n');
if (pos != NULL)
    *pos = '\0';
name[i++] = inputName;
}
printf("%s\n", name[0]); // prints Payne, why not Max???
printf("%s\n", name[1]); // prints Payne

最佳答案

对于情况1,“ doe”不是字符串。

情况2之所以起作用,是因为您正在使用字符串文字初始化指针。

情况3也是可行的,因为您将情况2中相同的初始化指针分配给情况1指针。您的名称数组指针基本上设置为指向name2指向的位置。

在情况4中,您声明了inputName,它指向一组10个字符。然后,每当您收到新输入时,便会将其写入相同的内存部分。然后执行以下操作:name[i++] = inputName;
您没有像您想的那样将新的char数组复制到name [i]。相反,您是在告诉name [i] char指针指向inputName。因此,正常情况下,名称将最后一次输入打印两次,因为这是inputName指向的内容以及两个名称char指针。

09-25 16:07