char *变量地址与char 变量地址

我将从以下两个声明和初始化中打印出地址和字符串:

char * strPtr = (char *) "This is a string, made on the fly."; char charArray [] = "Chars in a char array variable."; 

打印时,以下输出会出现变量charArray和strPtr的完全不同的地址。 问题是,“为什么?”

印刷:

  printf( "%10s%40s%20p\n", "strPtr", strPtr, &(*strPtr)); printf( "%10s%40s%20p\n", "charArray", charArray, charArray); 

输出:

  strPtr This is a string, made on the fly. 0x400880 charArray Chars in a char array variable. 0x7fff12d5ed30 

如您所见,不同的地址是:0x400880与0x7fff12d5ed30

在此之前声明的其余变量具有类似charArray的地址。

同样,问题是,“为什么地址如此不同?” 谢谢你的帮助。

因为字符串文字,例如“foo bar”被分配在比char数组“不同的地方”。

这是依赖于实现的 ,但是典型的实现将把字符串文字放在可执行文件的.rdata (“只读数据”)部分中,并且您的char数组在本地声明,因此进入堆栈。

当图像的不同部分加载到RAM中时,它们将被映射到截然不同的地址。

我猜测编译器/链接器将char数组放在堆栈上,而另一个字符串放入静态字符串表中。

文本“char数组变量中的字符”。 并且“这是一个字符串,在飞行中制作。” 彼此可能很近。 但是, char charArray[] = ...请求堆栈中的空间,其中复制了相应的文本位。 一旦操作系统完成虚拟化等操作,堆栈实际上与原始硬编码文本处于不同的范围内。

这是怎么回事 – 我记得在[ Unix:系统编程 ]中读到这个

1 替代文字

如您所见,初始化静态数据存储在堆上的不同位置,而不是未初始化的静态数据。

在这里要实现的关键是,在strPtr的情况下,你正在处理两个不同的对象,而在charArray的情况下,你只处理一个

charArray是一个单个数组对象,填充了"Chars in a char array variable." 串。

strPtr本身是一个单指针对象。 它的值是第二个匿名的,不可修改的数组对象的地址,该对象又包含"This is a string, made on the fly."的字符"This is a string, made on the fly." 串。

当您使用%p打印出charArray ,您将打印charArray[0]的地址(由于数组的特殊规则)。 当你打印出&(*strPtr) (它与strPtr )时,你打印的是前面提到的匿名,不可修改的数组对象的地址 – 这就是为什么它看起来与其他变量的地址有如此不同的原因参与其中。

如果使用%p打印出&strPtr ,您将看到变量strPtr本身的地址与其他局部变量的范围相似。