数组大小超过函数大小 (C++)
Posted
技术标签:
【中文标题】数组大小超过函数大小 (C++)【英文标题】:Array size exceeds function size (C++) 【发布时间】:2019-10-27 22:35:32 【问题描述】:首先让我说我对编程很陌生。解决方案可能非常明显。
基本上我需要编写一个代码,在 1 到 500 之间随机生成 10,000 个数字(有些数字会在整个数组中重复出现。问题是,要给所述数组赋值,我的意思是把它放在一个函数中输入 int 并从那里开始,但数组根本不适合函数。在这种情况下,有没有办法使用一个循环为数组中的所有变量赋值?可以在函数之外完成吗?
如果我尝试从函数中调用它,我会收到这 2 条警告消息:
1) 警告 C6262 函数使用 '40012' 字节的堆栈:超过 /analyze:stacksize '16384'。考虑将一些数据移动到堆中。
2) 警告 C6201 索引 '10000' 超出有效索引范围 '0' 到 '9999' 对于可能堆栈分配的缓冲区 'numsinarray'
编辑:我在 Visual Studio 2019 上工作
这是代码
#include <iostream>
#include <random>
using namespace std;
std::random_device seed;
std::mt19937 mersenneTwister(seed());
const int AmountOfNum = 10000;
const int RandomInt(int min, int max);
int NumGen(int min, int max);
int main()
const int RandomInt(int min, int max)
std::uniform_int_distribution<int> distribution(min, max);
return distribution(mersenneTwister);
int NumGen(int min, int max)
int numsinarray[AmountOfNum];
for (int i = 0; i <= AmountOfNum; i++)
numsinarray[i] = RandomInt(1, 500);
【问题讨论】:
嗯。您的代码看起来没问题,除了错误所说的数组对于您的平台来说可能太大了。为了完整起见,您在哪个平台上? 您需要使用 operator new 来在堆上分配足够的空间来溢出袋子。 我在 Visual Studio 2019 上工作。你的意思是用新的替换数组的变量吗? 你应该直接使用std::vector
而不是new
【参考方案1】:
欢迎来到堆栈溢出,讽刺的是这里的问题是堆栈溢出。 在这段代码 sn-p 中,您分配了 10'000 个 4 个字节的整数,总共 40'000 个字节,这对于堆栈中的东西来说是很多的。
int numsinarray[AmountOfNum];
什么是堆栈?:stack 是您的操作系统为执行程序而分配的内存区域,它是保存局部变量、函数调用、返回值等的地方... 这有助于跟踪函数调用以及 CPU 运行完函数时返回的位置。
我的问题的解决方案是什么?:(Dynamic memory) 解决方案很简单,但也有责任。每当您尝试分配大的东西时,您必须考虑Heap。heap 是您可以获得尽可能多的内存的地方,因为您的操作系统和 PC 可以处理。
如何从堆中分配?
int* numsinarray = new int[AmountOfNum]; // syntax : TYPE* ptr = new TYPE[NB];
就这么简单,但还记得我之前提到的责任吗? 每当您从堆中分配时,您必须在完成后显式释放您保留的内容(不再需要数据)
如何释放?
delete[] numsinarray;
语法是:
delete[] ptr; // if its an array or
delete ptr; // if you allocate only one element
您的代码将是:
int main()
int* my_arr = NumGen(0, 500);
// use my array.. more code...
delete[] my_arr; // free my array I dont need it anymore
int RandomInt(int min, int max) // the const here is useless (I removed it)
std::uniform_int_distribution<int> distribution(min, max);
return distribution(mersenneTwister);
int* NumGen(int min, int max)
int* numsinarray = new int[AmountOfNum];
for (int i = 0; i < AmountOfNum; i++) // must be < not <= the latter will reach AmountOfNum
//which is already out of the array (array's in C/C++ are indexed in [0..n-1]
numsinarray[i] = RandomInt(1, 500);
// do more processing maybe return the pointer of you array
return numsinarray;
请确保您没有重复释放指针或在释放后再次使用它。
这听起来很复杂的任何替代方案? 遗憾的是,要成为一名优秀的程序员,您必须处理堆问题,但如果您正在寻找其他解决方案,标准库 (STL) 为我们提供了std::vector,它更易于操作、处理和自动处理堆问题。
【讨论】:
忍不住喜欢你的开场白!这绝对值得 ? 投票。【参考方案2】:int numsinarray[AmountOfNum];
您正在调用堆栈上静态分配 (sizeof(int) * AmountOfNum) = (4 * 10000) = 40000 字节,但您的项目的堆栈大小设置为 16384 字节。正如警告所说,使用new[]
或std::vector
在堆上动态分配数组。
for (int i = 0; i
数组是从 0 开始索引的。您的数组的有效索引是 0..9999,但是您的循环使用 <=
而不是 <
使其尝试写入索引 10000,从而超出数组的范围进入周围的内存。
试试这个:
#include <iostream>
#include <random>
#include <vector>
std::random_device seed;
std::mt19937 mersenneTwister(seed());
const int AmountOfNum = 10000;
const int RandomInt(int min, int max);
int NumGen(int min, int max);
int main()
const int RandomInt(int min, int max)
std::uniform_int_distribution<int> distribution(min, max);
return distribution(mersenneTwister);
int NumGen(int min, int max)
std::vector<int> numsinarray(AmountOfNum);
for (int i = 0; i < AmountOfNum; i++)
numsinarray[i] = RandomInt(1, 500);
/* alternatively:
std::vector<int> numsinarray;
numsinarray.reserve(AmountOfNum);
for (int i = 0; i < AmountOfNum; i++)
numsinarray.push_back(RandomInt(1, 500));
*/
// use numsinarray as needed...
return ...;
【讨论】:
很好,但是您的int NumGen(int min, int max)
版本仍然没有返回任何内容!【参考方案3】:
应该认真对待编译器给出的警告(我将在下面处理这些)。它还应该至少给你一个警告:你的函数 NumGen
被声明为(返回一个)int
但它实际上并没有返回任何东西!
您将遇到的另一个问题是您无法访问您在函数中“创建”的数组numsinarry
。为了解决这个问题和警告之一,您应该声明(并定义)“NumGen”函数作为返回 指向 int 的指针 - 然后您可以将该返回的指针作为数组访问。
所以,这是一个可能的版本(我添加了三斜线 cmets,并在其中进行了一些更改):
int* NumGen(int min, int max) /// Use int* to say we shall return a pointer (array)¬
// int numsinarray[AmountOfNum]; /// This is too big for the "stack" - see below.
int *numsinarry = new int[AmountOfNum]; /// This creates the 'array' on the "heap"
// for (int i = 0; i <= AmountOfNum; i++) /// This goes one beyond the end of the array
for (int i = 0; i < AmountOfNum; i++) /// The last element has index AmountOfNum - 1
numsinarray[i] = RandomInt(1, 500);
return numsinarry; /// Return this so we can use the data!
“创建”numsinaarry
(所谓的 自动 变量)的问题是编译器将(尝试)从分配给函数的内存中为其分配空间被调用;这就是所谓的 stack,根据您引用的警告,它在您的平台上的限制为 16384 字节(16 KB)。使用 'new' 操作符从我们称为 heap 的地方分配所需的内存(40,000 字节) - 实际上,这就是您的程序可用的内存总量(这些天,巨大的)。
当您最终从main
调用此函数时,您将执行以下操作:
int *data = NumGen(1, 500); // These are the limits for min & max you indicated!
然后您可以使用普通索引系统访问data
“数组”的元素,例如:int test = data[123];
。
还有一件非常重要的事情:你永远不应该忘记,在某个时候,释放分配的内存!释放使用new[]
运算符分配的内存的方法是使用'delete[]` 运算符,如下所示(当您完成数据时):
delete[] data;
请随时要求任何进一步的澄清和/或解释。
【讨论】:
以上是关于数组大小超过函数大小 (C++)的主要内容,如果未能解决你的问题,请参考以下文章
在没有向量、指针的情况下在 C++ 中在运行时增加数组大小 [关闭]
Array.Sort 谷歌内核 数组大小超过10 排序字段都一致 返回的数组非原数组