23、关于字符串常量存储的一个易犯错误的地方

1、如下示例程序中:

示例代码

// Win32_test.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include "iostream"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	char *a = "hello";
	char *b = "hello";
	char s[] = "hello";
	//*b = 'b'; error
	s[0] = 'b';
	//a,b指针指向的是常量区的数据"hello”,而s[]在栈中分配内存并复制了
	//常量数据"abcdef”的拷贝。所以,我们修改字符数组s,实际上只是修改的在
	//栈中的拷贝,而没有修改文本常量区的数据。
	if (a == b)
		cout << "a == b" << endl; //输出a == b
	if ("test" == "test")
		cout << "test == test" << endl; //输出test == test
	return 0;
}
示例代码
#include <stdio.h> 
int main() 
{ 
	char *p="abcdef"; //should be : const char * p = "abcdef";
	//...
} 
/*
apparently, var p is allocated from current stack frame, 
the string constant literal: "abcdef" lies in the .rdata segment,
if u use the expresstion: p[2]='W', which will change the rdata's data,
os refuse this action, but the compiler and linker pass.
so a running-error will popup.
*/

//another ex;
#include <stdio.h> 
int main() 
{ 
	char s[]="abcdef";//s在栈,“abcdef”在数据区
	//...
} 
/*
this behavior is okay, 
this memory from s is alloated from the current stack frame,
r-vale "abcdef" will be copies to that place that is already allocated 
through above step. notice! u change only the copy NOT origin, so this program 
may support 'reload'.

    可能我们觉得他们不会相等,实际是相等的,为什么?因为他们是字符串常量,存储在内存中的文字常量区(文字常量区—常量字符串就是放在这里的,程序结束后由系统释放)[2]

2、在[1]中,作者作出了相反的答案。但至少在我的电脑上,VS2008中,执行的是如程序中的结果,与[1]中所述有区别。

3、在[3]CSDN论坛的帖子中,对这个问题进行了讨论。

示例代码

//main.cpp
 int a=0;  //全局初始化区
 char *p1;  //全局未初始化区
 main()
 {
  intb;栈
  char s[]="abc";  //栈
  char *p2;     //栈
  char *p3="123456";  //123456\0在常量区,p3在栈上。
  static int c=0;  //全局(静态)初始化区
  p1 = (char*)malloc(10);
  p2 = (char*)malloc(20);  //分配得来得10和20字节的区域就在堆区。
  strcpy(p1,"123456");  //123456\0放在常量区,编译器可能会将它与p3所向"123456"优化成一个地方。
}

参考

[1] http://www.soidc.net/articles/1215485053486/20061202/1215945550035_1.html

[2] http://blog.163.com/zhoumhan_0351/blog/static/39954227200910288840539/

[3]http://topic.csdn.net/u/20081106/23/02545709-f008-41c5-86d0-d2eb8aa1e162_2.html

上一篇:LoginForm表单的执行过程


下一篇:VMTools和虚拟硬件升级