喵の窝

C99中的变长数组

前几天遇到个奇葩bug,一函数在返回时crash.通过堆栈信息得知函数返回时栈溢出,所以crash了.查看函数源码,发现如下片段

1
2
3
4
5
//...
char *someStr = "someStr";
int len = strlen(someStr);
char buffer[len + 1];
//...

其中,someStr的值是运行时获取的.
看到这段代码,我瞬间懵逼了.在我的世界观中,数组的长度必须是一个常量.而代码中数组长度是一个运行时变量,并且还能正常编译.这明显不科学.开始怀疑仁僧的我把代码复制到VS2015中,发现代码并不能通过编译,提示数组长度必须为常量.但是这段代码在linux环境中用clang或者gcc都能正常编译.

这么奇葩的问题显然超出了度娘可以解决的范围,于是果断Google之.原来C99标准中引入了变长数组,但是C++并不支持这个特性.而且如果数组过长会有潜在的风险.

看来,crash的原因是因为在栈上构建了一个过长的数组导致栈溢出.知道了原因就好办了,把数组malloc在堆上问题就解决了.

不过连C都支持的变长数组为什么到了C++就不支持了呢?Google的结果如下:C++要求变量的类型必须在编译时期就确定.而数组的类型不仅与数组元素的类型相关,还与数组元素的个数相关.如果数组的长度可以在运行时期确定,那么C++在编译时期就不能确定数组的类型了.所以到目前为止,C++都不支持变长数组.