我正在做一项关于C++结构的学校作业。分配不允许使用STL或new
/delete
。
我在杂志上代理商品。
struct PLACE {
int itemCount;
int etiquette[2];
};
struct SHELF {
int placesCount;
PLACE places[128];
};
struct RACK {
int shelvesCount;
SHELF shelves[128];
};
struct MAG {
int racksCount;
RACK racks[5];
};
现在,当我运行以下代码时,它运行得很好,但如果我将racks数组的长度更改为20左右,我会得到一个运行时错误(code.exe已停止工作)。
PLACE place1 = {1, {1,2}};
SHELF shelf1 = {2, {place1}};
RACK rack1 = {3, {shelf1}};
MAG mag1 = {1, {rack1}};
我似乎超出了某种记忆?我认为这不太可能,因为当我计算它时,(当机架长度为5时)我只使用((12*128)+4)*128+4)*5+4字节,大约是1MB。
EDIT:
我要求我的教练对此进行澄清。他告诉我,这可能比我的堆被超过,而不是堆栈,因为:(引用)
堆栈处理函数调用,超出堆栈可能是由例如递归,而这里我们处理的是大数据,所以这相当于超出了堆。
他还告诉我,我的计算机可能只有一个下限(大约4MB),而我们正在检查代码的服务器被分配了1GB来处理这么多数据。
不过,我不知道这是不是真的,因为根据我在网上读到的内容,堆栈和堆都可以分配变量,堆栈并不是纯粹为函数调用保留的,也为这些函数内部的变量保留的。。。
您在这里使用了大量自动存储持续时间。您的编译器和体系结构不太可能允许超过1Mb的此类内容。
幸运的是,解决方案微不足道。
使用std::vector
代替阵列:例如
struct MAG {
// int racksCount; no need for this if you use a std::vector
std::vector<RACK> racks;
};
std::vector
将其大部分有效载荷放在动态存储器中,这就是为什么这种方法会起作用。还有其他C++标准库容器,但一个很好的经验法则是使用std::vector
,除非你有充分的理由不这样做
是的,您用完了堆栈。
这种情况尤其如此,因为您正在shelf1
中复制来自place1
的数据,并且对于所有的oother都是一样的,所有这些都只是针对一个元素。使用std::vector
而不是静态数组。
如果因为这是一个赋值而不能,那么仍然可以使用new
/delete
来使用堆而不是堆栈。
如果没有,请交叉手指,并尝试使用:
MAG mag1 = {1, {{3, {{2, {{1, {1,2}}}}}}}};
丑陋的是,你不知道你正在填充什么对象,但应该在现代编译器上工作。