C 使用字符串文字进行数组初始化是否会导致两个内存存储?
C 使用字符串文字进行数组初始化是否会导致两个内存存储?,c,string-literals,array-initialization,C,String Literals,Array Initialization,“123454321”是一个字符串文字,字符串文字留出内存存储空间a由语句定义,该语句也会导致内存存储。也就是说,这个简单的语句chara[]=“123454321”导致两个内存存储,一个用于a,另一个用于“123454321”。是吗?是的,没错 请注意,=右侧的对象本身不是字符串文字;它是一个初始化表达式,编译器没有义务像存储字符串一样存储它。它可能会将其分解为多个部分,或者发出一系列即时存储,而不是复制初始值,或者甚至(理论上)发出对初始数据的缩短版本进行解压缩的代码。但不管它是如何编译的,
“123454321”
是一个字符串文字,字符串文字留出内存存储空间a
由语句定义,该语句也会导致内存存储。也就是说,这个简单的语句chara[]=“123454321”代码>导致两个内存存储,一个用于a
,另一个用于“123454321”
。是吗?是的,没错
请注意,=
右侧的对象本身不是字符串文字;它是一个初始化表达式,编译器没有义务像存储字符串一样存储它。它可能会将其分解为多个部分,或者发出一系列即时存储,而不是复制初始值,或者甚至(理论上)发出对初始数据的缩短版本进行解压缩的代码。但不管它是如何编译的,都会占用一些内存
如果编译器选择将初始值存储为字符串,则该值必须是不可变的,以便将其放置在只读内存中和/或与具有相同值的字符串文本共享<代码>另一方面,代码是可变的,可以更改。显然,它必须有自己的记忆
最后,有一种情况是编译器可能根本不保留蚂蚁空间。如果它能证明删除不会导致任何可见的更改,那么它可能会优化掉未使用的数组和初始值中的一个或两个,就像您问题中的示例代码一样。是的,没错
请注意,=
右侧的对象本身不是字符串文字;它是一个初始化表达式,编译器没有义务像存储字符串一样存储它。它可能会将其分解为多个部分,或者发出一系列即时存储,而不是复制初始值,或者甚至(理论上)发出对初始数据的缩短版本进行解压缩的代码。但不管它是如何编译的,都会占用一些内存
如果编译器选择将初始值存储为字符串,则该值必须是不可变的,以便将其放置在只读内存中和/或与具有相同值的字符串文本共享<代码>另一方面,代码是可变的,可以更改。显然,它必须有自己的记忆
最后,有一种情况是编译器可能根本不保留蚂蚁空间。如果可以证明删除不会导致任何可见的更改,那么它可能会优化掉未使用的数组和初始值中的一个或两个,就像您问题中的示例代码一样。谢谢您的检查!我想再问一个关于你的答案的问题<代码>它可能。。。和/或与另一个具有相同值的字符串文字共享
我在K&R(第2版)194p中读到“相同字符串文字是否不同是实现定义的,…”。共享另一个具有相同值的字符串文本是更常见的情况吗?@opol:大多数编译器在同一翻译单元中共享字符串文本。一些实现使用专门的链接器在翻译单元之间共享字符串文本。const
是不够的,因为main可以重新进入。如果使用了static
,则可能不会有额外的分配,无论是否为常量。“字符串文字是不可变的”,从技术上讲,字符串文字甚至不需要存储在任何地方。我对相关问题的回答中有一个例子。@dxiv:是的,这是一个很好的观点。初始值必须在可执行文件中的某个位置,但不必是字符数组;它可以是一系列立即数操作数。理论上,它甚至可以被计算出来,但那将是令人惊讶的。谢谢你的检查!我想再问一个关于你的答案的问题<代码>它可能。。。和/或与另一个具有相同值的字符串文字共享我在K&R(第2版)194p中读到“相同字符串文字是否不同是实现定义的,…”。共享另一个具有相同值的字符串文本是更常见的情况吗?@opol:大多数编译器在同一翻译单元中共享字符串文本。一些实现使用专门的链接器在翻译单元之间共享字符串文本。const
是不够的,因为main可以重新进入。如果使用了static
,则可能不会有额外的分配,无论是否为常量。“字符串文字是不可变的”,从技术上讲,字符串文字甚至不需要存储在任何地方。我对相关问题的回答中有一个例子。@dxiv:是的,这是一个很好的观点。初始值必须在可执行文件中的某个位置,但不必是字符数组;它可以是一系列立即数操作数。理论上,它甚至可以被计算出来,但那将是令人惊讶的。
int main()
{
char a[] = "123454321";
}