字符串初始化器会不会浪费内存?

nal*_*zok 4 c memory arrays embedded language-lawyer

要初始化一个char数组,通常我写:

char string[] = "some text";
Run Code Online (Sandbox Code Playgroud)

但是今天,我的一个同学说应该使用:

char string[] = {'s', 'o', 'm', 'e', ' ', 't', 'e', 'x', 't', '\0'};
Run Code Online (Sandbox Code Playgroud)

我告诉他放弃可读性和简洁性是疯狂的,但他认为用字符串初始化一个char数组实际上会创建两个字符串,一个在堆栈中,另一个在只读内存中.使用嵌入式设备时,这会导致内存中不可接受的浪费.

当然,字符串初始化器似乎更清晰,所以我将在我的程序中使用它们.但问题是,字符串初始化器会创建两个相同的字符串吗?或者字符串初始化器只是语法糖?

Som*_*ude 6

编辑后,两个定义之间没有区别.两者都将生成一个包含十个字符的数组,并初始化为相同的内容.

这实际上很容易验证:首先检查是什么sizeof给你两个数组,然后你可以使用eg memcmp比较两个数组.

第二次初始化几乎与第一次初始化相同,只有一次关键区别:第二次数组不会以字符串形式终止.

第一个创建一个包含十个字符的数组(包括终结符),第二个创建一个包含九个字符的数组.如果您不将数组用作字符串,那么您将使用第二次初始化保存一次元素.


Lun*_*din 6

char string[] = "some text";
Run Code Online (Sandbox Code Playgroud)

是100%相当于

char string[] = {'s', 'o', 'm', 'e', ' ', 't', 'e', 'x', 't', '\0'};
Run Code Online (Sandbox Code Playgroud)

你的朋友很困惑:如果string是局部变量,那么在这两种情况下你都会创建两个字符串.string驻留在堆栈上的变量和驻留在只读内存(.rodata)中的只读字符串文字.

没有办法避免只读存储,因为必须在某处分配所有数据.您无法在空中分配字符串文字.您所能做的就是将它从一个只读存储器段移动到另一个只读存储器段,最终将为您提供相同的程序大小.

前一种风格一般是首选,因为它更具可读性.它确实是一种语法糖.

但它也是首选,因为它可以简化一些称为"字符串池"的编译器优化,它允许编译器以"some text"更加内存有效的方式存储字符串文字.如果逐个字符地初始化字符串,则编译可能会或可能不会意识到它是只读字符串常量.