更改字符串数组中的单个字符

时间:2013-11-19 19:31:36

标签: c

运行以下代码时,为什么会出现挂起时错误?

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;
}

2 个答案:

答案 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_arraychar*的数组,并且该类型在技术上是可分配的。字符串文字实际上是const(我可能应该在上面说过它们的类型是const char*而不是char*)。因此,当您完成作业string_array[0] = "hI";时,您实际上正在向const char*投射char*。 C是一个非常宽容的"语言。 :)所以当你告诉它将const类型转换为非const类型时,它很乐意遵守。然后当你告诉它分配给现在的非const类型变量时,它再次乐于遵守。这就是为什么在运行时,当硬件和操作系统使用写保护内存来防止错误时,问题实际上不会出现的原因。

正如其他人所提到的那样,修复它的方法,并假设你确实要进行该分配,就是创建一个字符数组并将字符串文字复制到其中(例如,使用strncpy)。