我正在学习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指针。