内存不可写 char*
先看一个例子
/ //代码1 #include <string> main() { char *buf = "good morning."; char *p; p = strchr(buf, 'd'); *p = 'h'; // 此处不可以进行赋值.提示出错,内存不可写 printf("%s", p); return 0; } ///// //代码2 #include <string> int main(void) { char buf[] = "good morning."; char *p; p = strchr(buf, 'd'); *p = 'h'; // 此处赋值不会有问题. printf("%s", p); return 0; }
这是为什么呢?关键原因在于"good morning."存放的位置,"下面进行分析
(1) 可以肯定的是不论是代码1 还是代码2, "good morning."都是存放在文字常量区中的。文字常量区是一个静态存储区, 对它进行修改是不允许的。
(2) 代码1 和代码2 中 buf 都是存放在函数的栈中。
(3) 代码2在运行时会将静态区中的 “good morning." 复制一份到函数的栈中, 而 buf指向的是栈内的地址,因此对它进行修改不会产生任何问题。 但是代码1不会将静态区中的 "good morning."复制到栈中,因此对指针的内容进行修改会产生错误。
(4) 事实上脱离编译器而谈论这个问题是没有意义的,因为一些编译器可能是采用以上的方式进行编译,而另外一些采用其他的方式,可能代码1和代码2都产生错误, 也可能都没有运行错误。
事实上一个由 C / C++编译的程序占用的内存分为以下几个部分:
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈,默认可读写.
2、堆区(heap) — 一般由程序员分配释放(new、malloc等), 若程序员不释放,程序结束时可能由 OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,默认可读写
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束后由系统释放 ,默认可读写.
4、文字常量区 —常量字符串就是放在这里的,程序结束后由系统释放,只读.
5、程序代码区—存放函数体的二进制代码,只读.