0

我是新编程,我发现了一个问题,我正在定义一个像这样的 c++ 数组

double name[512][512]

但是当我在 Windows 上运行它时(它编译时没有错误)它崩溃了。当我在 Linux(Ubuntu)上运行时,它运行它应该如何运行而不会出现问题。我认为 Windows 限制了我的程序可以占用的内存,对吗?我该如何解决?感谢所有可以帮助我的人。

4

3 回答 3

6

(因为你没有提供 MCVE)你的name数组是一个自动变量,所以它被分配在调用堆栈上。

顺便说一句,问题在于 RAM(由操作系统管理用户空间程序不直接使用RAM,而是使用虚拟内存),而在于进程的虚拟地址空间(其堆栈段)。在 Linux 上,您可以使用(参见proc(5)pmap(1))查询进程的虚拟地址空间。并阅读操作系统:三个简单的部分来了解操作系统的作用。/proc/

请注意,在 x86-64sizeof(name)上可能是 2097152 字节。

调用堆栈的大小是有限的。在 Linux 上,通常的限制是 4 或 8 兆字节(但有办法改变它),在 Windows 上据说是 1 兆字节。你有一个堆栈溢出

你很可能超过了这个限制。考虑使用一些动态内存分配(例如,使用new; 但是通过使用更高级别的 C++ 构造,例如容器智能指针,您通常应该避免显式使用它)。大多数 C++ 标准容器,特别是std::vector(但不是std::array)将它(堆)用于内部数据。

根据经验,每个调用帧应该相当小(例如千字节)。

如果您在 Linux 上编译,编译器可能会警告您。 g++ -Wall -Wextra -Wstack-usage=1500 -g还要学习使用gdb调试器。害怕未定义行为

您还可以使用一些额外的,例如提供矩阵的Boost(或其他东西),或者拥有自己的Matrix 抽象数据类型(它将堆分配其数据)。注意5规则

花几周时间阅读一些优秀的C++ 编程书籍,但要注意 C++ 是一种非常困难和复杂的编程语言(因此请阅读SICP以了解更一般的编程概念并尝试一些Scheme实现,例如Racket)。稍后,您可以阅读一些有关垃圾收集的(其中的概念与内存管理相关)。

于 2018-04-30T05:38:23.980 回答
0

您正在遇到堆栈溢出。

sizeof(double)在 Windows 上为 8。

因此,8*512*5122MB。如果我没记错的话,Visual Studio 编译器的默认堆栈大小是 1MB。链接器上的/STACK编译器开关可用于增加此大小。

正如其他人可能指出的那样,对于大型数组,使用堆(malloc/new、free/delete)而不是使用数组变量占用大量堆栈。

于 2018-04-30T05:40:01.130 回答
0

您可能正在尝试在堆栈上分配数组,而 Windows 系统上的堆栈大小较小。如果是这种情况,请将数组设为全局或static,问题就会消失。

另一种选择是动态分配数组。例如:

struct Array {
    double vals[512][512];
};

// in a function:
auto name_guard = std::make_unique<Array>();
auto &name = name_guard->vals;

这里name_guard确保在不再需要时(由 的生命周期确定name_guard)将删除存储,并且与问题中name的含义相同name。注意name一定不能让守卫对象活得更久。

于 2018-04-30T05:37:15.220 回答