字符串分配

时间:2011-12-27 13:45:07

标签: c variable-assignment

我正在使用Microsoft Visual Studio环境。我遇到了一种奇怪的行为

 char *src ="123";
 char *des ="abc";
 printf("\nThe src string is %c", src[0]);
 printf("\tThe dest string is %c",dest[0]);

 des[0] = src[0];

 printf("\nThe src string is %c", src[0]);
 printf("\tThe dest string is %c",dest[0]);

结果是:

1 a
1 a   

这意味着des[0]未被初始化。因为src指向字符串的第一个元素。我想根据规则这应该有效。

5 个答案:

答案 0 :(得分:3)

这是未定义的行为:

des[0] = src[0];

请改为尝试:

char des[] ="abc";

答案 1 :(得分:1)

由于src和des是用字符串文字初始化的,因此它们的类型实际上应该是const char *,而不是char *;像这样:

const char * src ="123";
const char * des ="abc";

从未为它们中的任何一个分配内存,它们只是指向预定义的常量。因此,语句des[0] = src[0]是未定义的行为;你试图在那里改变一个常数!

任何体面的编译器都应该警告你关于从const char *char *的隐式转换......

如果使用C ++,请考虑使用std::string代替char *,使用std::cout代替printf

答案 2 :(得分:1)

ISO / IEC 14882(编程语言 - C ++)第2.13.4节说:

  1. 字符串文字是由双引号括起的字符序列(如2.13.2中所定义),可选地以字母L开头,如“...”或“L”......“。不以L开头的字符串文字是普通的字符串文字,也称为窄字符串文字。普通的字符串文字具有类型“n const char数组”和静态存储持续时间(3.7),其中n是下面定义的字符串的大小,并使用给定的字符进行初始化。 ...

  2. 是否所有字符串文字都是不同的(即存储在非重叠对象中)是实现定义的。尝试修改字符串文字的效果是未定义

答案 3 :(得分:1)

在C中,"123"等字符串文字存储为char({+ 1}}在C ++中的数组。这些数组存储在存储器中,以便在程序的生命周期内可用。尝试修改字符串文字的内容会导致未定义的行为;有时它会“工作”,有时它不会,取决于编译器和平台,所以最好将字符串文字视为不可写。

请记住,在大多数情况下,“N元素数组const char”类型的表达式将转换为“指向T的指针”类型的表达式,其值为第一个的位置数组中的元素。

因此,当你写

T

表达式 char *src = "123"; char *des = "abc"; "123"从“{3}元素"abc"数组”转换为“指向char”的指针, char会指向src中的'1'"123"会指向des中的'a'

同样,尝试修改字符串文字的内容会导致未定义的行为,因此当您编写

"abc"

编译器可以自由地以任何方式处理该语句,从完全忽略它到完全按照你期望的方式处理它之间的任何事情。这意味着字符串文字或指向它们的指针不能用作des[0] = src[0]; strcpystrcat等调用的目标参数,也不能用作参数像memcpy之类的电话。

答案 4 :(得分:0)

  

vinaygarg :这意味着des[0]未被初始化。因为src指向字符串的第一个元素。我想根据规则这应该有效。

首先你必须记住* src和* dst被定义为指针,仅此而已。

所以你必须问自己究竟什么是“123”和“abc”以及为什么它不能改变?好吧,简而言之,它存储在应用程序内存中,即read-only。为什么?字符串必须与程序一起存储,以便在运行时可用于您的代码,理论上您应该收到编译器警告,以便将非const char*分配给const char *。为什么是read-only?需要保护exe和dll的内存不被覆盖,因此必须是只读的才能阻止错误和病毒修改执行代码。

那你怎么能把这个字符串变成可修改的内存呢?

// Copying into an array.
const size_t BUFFER_SIZE = 256;
char buffer[BUFFER_SIZE];
strcpy(buffer, "abc");
strncpy(buffer, "abc", BUFFER_SIZE-1);