不同的字符串初始化会产生不同

时间:2009-10-30 00:04:23

标签: c

为什么我使用以下方法,用于将字符串中的所有字符转换为大写,

while (*postcode) {
    *postcode = toupper(*postcode);

    postcode++;
}

使用以下参数,

char wrong[20];
strcpy(wrong, "la1 4yt");

但以下情况并非如此,尽管它们是相同的?

char* wrong = "la1 4yt";

我的程序崩溃试图写入非法地址(我认为是一个段错误)。这不是malloc的问题吗?不是无效的?它应该不是......

通过调试我发现它在尝试将第一个字符分配为大写时崩溃了。

任何帮助表示赞赏!

5 个答案:

答案 0 :(得分:5)

char* wrong = "la1 4yt";

这声明了一个指向字符串常量的指针。常量无法修改,这就是您的代码崩溃的原因。如果你写的更迂腐<​​/ p>

const char* wrong = "la1 4yt"; // Better

然后编译器会抓住错误。您应该在声明指向字符串文字的指针而不是创建数组时执行此操作。

另一方面,这为20个字符分配读/写存储空间,因此可以写入空格。

char wrong[20];

如果你想将它初始化为上面的字符串,你可以这样做,然后就可以改变它。

char wrong[20] = "la1 4yt"; // Can be modified
char wrong[]   = "la1 4yt"; // Can be modified; only as large as required

答案 1 :(得分:2)

char * whatever = "some cont string";

是只读的。

答案 2 :(得分:2)

在第二个变体中,"la1 4yt"是常量,因此位于只读段中。只有常量的指针(wrong)是可写的。这就是你得到段错误的原因。然而,在第一个例子中,一切都是可写的。

这个可能很有趣:http://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c/

答案 3 :(得分:2)

请参阅C FAQ列表中的Question 8.5

答案 4 :(得分:1)

当你这样做时

char wrong[20] = "la1 4yt";
编译器将字符串文字{'l', 'a', '1', ' ', '4', 'y', 't', '\0'}的元素复制wrong数组的相应元素;当你做的时候

char *wrong = "la1 4yt";

编译器将wrong分配给字符串文字的地址。

字符串文字是char[](字符数组),而不是const char[] ...但你无法改变它们!

来自标准的报价:

6.4.5 String literals
6   It is unspecified whether these arrays are distinct provided
    their elements have the appropriate values. If the program
    attempts to modify such an array, the behavior is undefined.

当我使用字符串文字初始化char *时,我通常也告诉编译器我不会通过在定义中添加const来更改该字符串文字的内容。

const char *wrong = "la1 4yt";

修改

假设你有

char *test1 = "example test";
char *test2 = "test";

编译器创建了1个单字符串文字,并使用该单字符串文字来初始化test1和test2。如果您被允许更改字符串文字...

test1[10] = 'x';       /* attempt to change the 's' */
printf("%s\n", test2); /* print "text", not "test"! */