【问题标题】:Why do we not declare arrays with variable size?为什么我们不声明可变大小的数组?
【发布时间】:2017-05-23 16:38:44
【问题描述】:

我的主管在我的 C 代码中看到了类似于:

size = f(some parameters);
int array[size];

他说最好用malloc 分配这样的数组。他的描述是这样的:

像这样在堆栈上分配它需要您的堆栈在程序的整个运行时保持有效。

我不知道他的意思,所以这与我记得的会议结束时他的措辞一样接近,但不知道实际含义。他是什么意思? (或者,也许有人可以解释不以这种方式声明数组的另一个原因)。

【问题讨论】:

  • 你的记性很好。本地分配的数组不会:) 一旦你离开这个函数,这样一个定义分配的内存就会被释放。 malloced 内存不是这种情况,在您手动 free 之前,它一直处于分配状态。但是每一个都有用例,你不能说一个比另一个更好/
  • 如果你不在函数之外泄漏array,就不用担心终身问题,但另一个重要的问题是,如果大小导致堆栈溢出,则无法处理错误。
  • 几乎可以肯定某处存在重复,但基本上,可以在堆栈上分配一个局部变量,但定义它的函数必须保持活动状态,并且所有其他引用该变量的函数调用必须由这个函数(或由 那些 调用的函数)生成。当声明局部变量的函数退出时,该变量将超出范围和生命周期。此外,堆栈上的可用内存大小与堆上的可用内存量相比是有限的。
  • @Alex this previous question 可能是一本好书。

标签: c declare


【解决方案1】:

任何声明为本地的变量都只会在函数执行期间有效,因为它会被分配到栈中

如果你在声明它的函数之外需要这个数组,你需要用 malloc 分配它,但是如果你只在这个函数内部使用它并且在这个执行期间是可以的

请注意,任何局部变量都将使用堆栈内存,因此请确保您的数组永远不会大到足以导致程序中的堆栈溢出!

【讨论】:

  • 所以如果我在 main() 中这样声明,那我应该没问题?
  • @Alex 除非它太大而无法放入堆栈,这是非常有限的。
  • 如果堆栈溢出(哈哈,我们的网站),那么程序就会崩溃?
  • @Alex 会的。或者它不会。或者有时会。或者它会导致一些奇怪的东西。它是未定义的。
  • @Alex 堆栈溢出是指堆栈超出分配给它的区域,因此它可以开始覆盖其他变量、程序代码,甚至由于未映射的内存访问而导致系统崩溃。这就是为什么我们说“未定义的行为”,基本上任何事情都可能发生,你的代码可以正常运行,或者可以开始做一些从未被编程过的事情,这是利用系统的一种经典方法
【解决方案2】:

一般来说,在 中使用可变长度数组并没有什么问题。数组将存在于它声明的范围内,就像任何其他变量一样。这是您应该始终牢记的事情,所以当然,如果您在函数中声明 VLA 并尝试返回指向它的指针,这是一个错误(一旦您离开函数,它就不再存在)。

不使用VLAs的原因:

  • 如果您在从创建它的函数返回后仍需要该数组,当然不能使用它,如上所述,但对于任何具有自动存储的对象都是如此
  • 堆栈空间有限,因此如果您的数组非常大,最好动态分配它。
  • 使 VLA 成为可选。因此,您使用 VLA 的代码可能不再适用于符合标准的 C11 编译器。

【讨论】:

  • 什么是 VLA?只是想弄清楚在 C11 中究竟什么是行不通的。
  • Variable Length Aarray -- 在 C11 中是可选的,因此编译器可以忽略该功能并且仍然符合 C11
  • @FelixPalmen 能否请您参考一下使其可选的段落?
  • 6.7.6.2 4 (可变长度数组是实现不需要支持的条件特性;参见 6.10.8.3。)
  • @EugeneSh。您知道吗,如果您不在评论中添加@,那么答案发布者(在本例中为 Felix)总是会收到通知?所以这次你不必放@FelixPalmen。虽然他确实需要通知你,但忘记了。
猜你喜欢
  • 2015-09-11
  • 2012-11-10
  • 2020-10-22
  • 1970-01-01
  • 2016-04-20
  • 1970-01-01
  • 2012-01-20
  • 2021-01-08
  • 2011-04-07
相关资源
最近更新 更多