char* 和字符串常量

  在代码调试过程中,还发现了一个比较诡异的事情,char*在使用malloc分配地址之后,如果对其使用字符串赋值,地址竟然会改变!!!逆天啊。

  看下面的代码:

  char *pName = (char *)malloc(sizeof(char) * 100);
  pName = "se";

  char *pName = (char *)malloc(sizeof(char) * 100)句为pName分配地址之后,再指向pName = "se",pName的地址会变化。注意指针的赋值,是将指针指向一个新的地址,那么也就是将指针pName指向了"se"的地址。再考虑下面的错误代码,就可以更明白“可以为指针赋值的都是地址”这个道理了:

  int *pi;
  pi = 1;  //Error

 

接下来从头至尾分析上面的代码:

  char *pName = (char *)malloc(sizeof(char) * 100);
  char *result = (char *)malloc(sizeof(char) * 50);

  此句在执行之后,会为pName和result分配各一个地址,调试结果显示为:

 

而在对其进行字符串赋值result = "se";执行 之后,result的地址竟然变化了:

 

  暂时只是奇怪,还不能知道为什么会变化。再对pName进行字符串赋值,(由于个人习惯还是赋值”se”),result和pName竟然指向了同一个地址0x0033544;而如果为pName赋值另外一个字符串,两者就会指向不同的地址。也就是说,char*被字符串赋值之后,指向的是字符串常量的地址。见下面的截图对比:

 

  再看地址的数值,malloc所取得的值是0x0015xxxx系列,而字符串常量则位于0x00f4xxxx系列,也就是相差很远,是不是处在不同的段呢?

  进而查阅资料,发现malloc函数是动态分配内存,在堆上开辟内存空间,而字符串常量则是存储在常量存储区;两者位于不同的区域,和上面的分析一致。那么result = "se"句,是对指针result的赋值;指针的赋值是将指针指向一个新的地址。也就是说上句将"se"的地址赋值给了result,”se”代表了地址。

  其实C中的字符串存储于常量存储区,其本身即代表了字符串的首地址。char*类型的指针,则是可以指向堆区、栈区、常量存储区任意其一,对应地,常见的char*的指针的指向也是有上面提到的这三种情况:

  char c;
  
char* pc = &c;   char* pStr = “se”;   char* pChars = (char*) malloc(sizeof(char)*30);

  上面代码中:

    •  pc指向的是栈区中的字符c的地址;
    •  pStr指向的是常量存储区中字符串”se”的地址;
    •  pChars则是指向malloc函数在堆区开辟的空间。

  再往深处扒,详见下篇。

posted @ 2013-04-09 21:25  czl-sy  阅读(3796)  评论(18编辑  收藏  举报