• 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

  • 相关阅读:
    https authorization basic
    第二十一章 单例模式
    第十九章 组合模式
    第十八章 备忘录模式
    第十七章 适配器模式
    第十六章 状态模式
    新博客~
    CF922D Robot Vacuum Cleaner
    BZOJ1767 [CEOI2009]harbingers
    树的直径学习笔记
  • 原文地址:https://www.cnblogs.com/mydomain/p/2095434.html
Copyright © 2020-2023  润新知