我将假设这只是示例代码,因为如果您的意图只是打印数字0..n
,那么您绝对没有理由为此使用数组:-)
对于您的实际问题,该alloca
函数,如malloc
,分配了一些字节。如果你然后把它当作你有许多int
值(几乎可以肯定大于一个字节),那不会很好。这实际上在对话框中得到确认,您会看到大小为 10 但每个数组元素占用 4 个:
Size: 10
Data: <> 00 00 00 00 01 00 00 00 02 00
\_________/ \_________/ \____
arr[0] arr[1] ar
您需要做的是:
int *arr = (int*) alloca(n * sizeof(*arr)); // n ints, not bytes.
无论如何,我会避免 alloca
,因为:
- 这真的不标准;和
- 如果它不能分配空间,它就会有行为不端的恼人习惯,而不是像那样引发异常
new
。
最后一点,Linux doco foralloca
states(我的重点):
alloca() 函数返回一个指向已分配空间开头的指针。如果分配导致堆栈溢出,则程序行为未定义。
如果你想要一些你不必担心自己取消分配的东西,现代 C++ 有智能指针,所以你可以使用类似的东西:
std::unique_ptr<int[]> arr(new int[n]);
当该arr
变量超出范围时,为其分配的内存将自动释放。您可以在原始代码的完整变体中尝试:
#include <iostream>
#include <memory>
void print_vals(size_t n) {
std::unique_ptr<int[]> arr(new int[n]);
for (size_t i = 0; i < n; i++)
arr[i] = static_cast<int>(i);
for (size_t i = 0; i < n; i++)
std::cout << arr[i] << ' ';
std::cout << '\n';
}
int main() {
print_vals(5);
print_vals(10);
}
顺便说一句,您会注意到我也更改为使用size_t
而不是int
大小和索引 - 我相信这更合适。现在,当然,这使用堆而不是堆栈,但根据之前关于alloca
.
如果你保证对大小有一些限制,你可能会更有可能成功,例如:alloca
void print_vals(size_t n) {
if (n >= 100) {
doSomethingIntelligent();
return;
}
int *arr = (int *)alloca(n * sizeof(*arr));
...
}
但这实际上并不能保证它的安全性,如果你要这样做,你也可以使用固定缓冲区,因为你会知道最大大小:
void print_vals(size_t n) {
int arr[100];
if (n >= sizeof(arr) / sizeof(*arr)) {
doSomethingIntelligent();
return;
}
...
}
我想提出另一种解决方案:如果您的意图是尽可能高效,您可以使用混合方法。我的意思是使用低于一定大小的本地缓冲区并仅在需要时分配内存:
void print_vals(size_t n) {
// Default to using local buffer.
int localBuff[100];
int *arr = localBuff;
// If more space needed, allocate an auto-freeing smart pointer.
std::unique_ptr<int[]> allocBuff;
if (n >= sizeof(localBuff) / sizeof(*localBuff)) {
allocBuff.reset(new int[n]);
arr = allocBuff.get();
}
// Here, arr points to to a big-enough buffer.
...