c 数组初始化问题
话说上次修改 icecast server 的代码时,看到下面一段代码
1 | if (plugin->contenttype == NULL) { |
如果是写 java 的话, 很明显,上面地方可以不注释, plugin->contenttype
相当于被赋值了2次,
但是由于是 c 代码, 不注释看着感觉有种会造成内存泄漏的感觉。
于是, 下面证明一下。
首先, 上一段测试代码
1 | char *returnStr1(){ |
首先, 对于 c 来说, 字符串有上面 2 种创建方式,(应该有能多钟, 不过我看的c代码大都只有以上2种)
由于程序的内存区域分 栈,堆, 代码区 。。。 所以最简单的方式就是直接打印她们的内存地址。
结果如下
1 | str1: 0x100000f71 |
很明显, 她们不在一个区, 网上查了下,栈区地址高,堆区地址低,所以
str1 的写法是创建在 堆
的。
str2 的写法是创建在 栈
的。
而向 栈
申请的空间在离开函数后就释放了。
很明显, 下面没打印出来。
ps, 其实, 用 clang 编译警告也能看出。
1 | memory_leak.c:28:12: warning: address of stack memory associated with local variable 'p' returned [-Wreturn-stack-address] |
但是
网上也查了下, 结果发现并不是。。。
可以试试看 这么写:
1 | char *returnStr1(){ |
编译会警告
1 | memory_leak.c:20:7: warning: incompatible pointer to integer conversion assigning to 'char' from 'char [13]' [-Wint-conversion] |
运行的时候会报错。
1 | name: 0x7fc99b4033d0 |
原来, 其实 char *p="hello world!";
这种写法相当于 const char *p="hello world!";
他其实是 创建了一个常量,然后将指针指向了他。 而这个常量是存储在 initialized data
区。 不可变的。
这里盗下图
结论
所以, 其实最上面的代码并不会造成内存泄漏, 而因为对常量重赋值直接报错。 (ps 在gcc 中会报 sengment error)
reference
http://stackoverflow.com/questions/19656025/why-is-char-on-the-stack-but-char-on-the-heap