所以,如果我这样做:
char * a = "hello";
“hello”存储在RODATA部分中并指向它。如果我这样做:
char a[10] = "hello";
“hello”以10个字节的数组存储在STACK中,称为。
当我这样做时会发生什么:
char * a[10] = {"hello", "hi"}
因此,我们有一个包含10个字符指针的数组,这些指针将存储在STACK中。但是字符串文字怎么样?他们是否进入RODATA部分?
另外,argv
会发生同样的事情吗?
答案 0 :(得分:4)
char *a[10] = {"hello", "hi"}
数组的元素是指向字符串文字的指针。作为任何字符串文字,它们也是不可修改的,并且实现可以将它们存储在只读存储器中。
*a[0] = 'g'; // undefined behavior, modifying a string literal
a[0] = "bla"; // ok, modifying the pointer
现在提出第二个问题:
此外,argv也会发生同样的事情吗?
不,因为它们不是字符串文字。可以修改argv
中的指针和指向的字符串。这是由C标准保证的。
(C99,5.1.2.2.1p2)“参数argc和argv以及argv数组指向的字符串应该可由程序修改,并在程序启动和程序终止之间保留它们最后存储的值。” / p>
答案 1 :(得分:3)
嗯,正在浏览gcc -S
:
cnicutar@cvm:~$ head try.S
.file "try.c"
.text
.Ltext0:
.section .rodata
.LC0:
.string "hello"
.LC1:
.string "hi"
或者,从二进制文件:
cnicutar@cvm:~$ objdump -s -j .rodata try
try: file format elf32-i386
Contents of section .rodata:
80484e8 03000000 01000200 68656c6c 6f006869 ........hello.hi
80484f8 00 .
这是该计划:
int main()
{
char * a[10] = {"hello", "hi"};
(void)a;
return 0;
}
答案 2 :(得分:2)
您的第一个假设可能适用于您的情况,但在其他平台和编译器上并不一定如此。但就你的问题而言,让我们假设它是。
你的第二个假设是不正确的。 "hello"
存储在与第一种情况相同的位置。只是它的字符(和尾随的0)被复制到堆栈中的a
(就C而言,它也不是一个明确定义的术语)。
在你的第三个例子中
char * a[10] = {"hello", "hi"}
"Hello"
和"hi"
存储在第一个示例中的任何位置,例如RODATA。第一个字符的指针存储为a
的前两个元素
答案 3 :(得分:1)
char * a[10] = {"hello", "hi"}
所以,我们有一个10个字符的数组
这不正确。我们有10个(本地)指向chars(或char数组)的指针。 “hello”和“hi”将像第一个例子一样存储在数据部分中。
答案 4 :(得分:1)
在第三种情况下,你有一个10个指针的数组,它使用10 * sizeof(char*)
个字节的内存。前两个元素指向数据段中相应的常量字符串。
答案 5 :(得分:1)
在String literals: Where do they go?
进行了长时间的讨论它们将在某个地方,具有静态存储持续时间。除此之外,它将取决于您的编译器。
你将拥有,例如(在一个带有1个字节指针的机器上,因为我很懒)
RODATA:
0x00: hello0
0x06: hi0
Stack:
0xA0: 0x00
0xA1: 0x06
0xA2: 0x00
[...]