运行以下代码时,为什么会出现挂起时错误?
int main(void)
{
char *string_array[2];
string_array[0] = "hI";
string_array[1] = "tHERE";
string_array[0][0] = 'H';
return 0;
}
但是,如果我调用单个字符串字符并使用相同的“句柄”打印它就可以了。(参见下面的工作代码)
int main(void)
{
char *string_array[2];
string_array[0] = "hI";
string_array[1] = "tHERE";
printf("%c", string_array[0][0]); //Prints out h, the first char of the first string in the array
return 0;
}
答案 0 :(得分:2)
char *string_array[2];
string_array[0] = "hI";
string_array[1] = "tHERE";
string_array
指向字符串文字所在的位置。
字符串文字hi
位于只读位置,无法修改。试图修改它们会导致未定义的行为。
要修改,请分配足够的内存,包括空终止字符,然后复制字符串。
答案 1 :(得分:0)
当您在代码中说出"Hello World"
时,这是一个字符串文字。当您运行程序时,这些字符(加上终止\0
)将放置在您的程序中的某个位置。记忆。每次"Hello World"
出现在您的代码中时,它都会替换为该字符串文字开头的内存地址(char*
)。这样,它就像一个普通的C字符串(即,你有char*
指向字符串中的第一个字符,最后一个字符后跟\0
所以你可以告诉字符串结束的地方)。但是,有一个重要区别:字符串文字不会放在其他变量所在的内存的同一部分中。具体来说,字符串文字所在的内存部分(通常)是只读的。这是物理表征的一种观点。从语言的角度来看,我们只是说"字符串文字是常量"意思是他们不能被分配。
所以当你说:
string_array[0] = "hI";
string_array[0][0] = 'H';
string_array[0]
指向一个字符串文字(" hI")根据C不可写。当你说string_array[0][0] = 'H';
时你试图对字符串进行赋值文字。物理上可能发生的是它尝试写入只读存储器地址,这会触发故障并导致操作系统终止您的进程。
编译器没有捕到这个的原因是因为string_array
是char*
的数组,并且该类型在技术上是可分配的。字符串文字实际上是const(我可能应该在上面说过它们的类型是const char*
而不是char*
)。因此,当您完成作业string_array[0] = "hI";
时,您实际上正在向const char*
投射char*
。 C是一个非常宽容的"语言。 :)所以当你告诉它将const类型转换为非const类型时,它很乐意遵守。然后当你告诉它分配给现在的非const类型变量时,它再次乐于遵守。这就是为什么在运行时,当硬件和操作系统使用写保护内存来防止错误时,问题实际上不会出现的原因。
正如其他人所提到的那样,修复它的方法,并假设你确实要进行该分配,就是创建一个字符数组并将字符串文字复制到其中(例如,使用strncpy
)。