【问题标题】:Why my c++ code runs on Linux but not on Windows, is there a problema with RAM memory? [closed]为什么我的 c++ 代码在 Linux 上运行而不在 Windows 上运行,RAM 内存有问题吗? [关闭]
【发布时间】:2018-10-10 04:35:39
【问题描述】:

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

double name[512][512]

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

【问题讨论】:

  • 你确定是这样吗?有些库可以在 linux 上运行,但不能在 windows 上确定!
  • 你在每个平台上用什么来构建你的程序?
  • 我猜测不同的默认堆栈大小。
  • 512 * 512 * 8 = 2097152(需要超过 2M 的堆栈空间)。更好的是double (*name)[512];,然后是name = malloc (512 * sizeof *name);,它将动态分配相同数量的字节,并允许您通过指向512 字符数组的指针进行相同的访问。
  • 我们应该为来自新人的问题提供奖励,其中答案是Stack Overflow。 :)

标签: c++ linux windows memory memory-management


【解决方案1】:

猜测(因为您没有提供 MCVE)您的 name 数组是 automatic variable,因此它被分配到 call stack

顺便说一句,问题不是在 RAM 中(由 operating system 管理;user-space 程序不使用 直接 RAM 但 virtual memory)但在您的processvirtual address space(它的堆栈段)中。在 Linux 上,您可以使用/proc/(请参阅proc(5)pmap(1))来查询您的进程的虚拟地址空间。并阅读Operating Systems: Three Easy Pieces 以了解操作系统的作用。

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

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

您可能超过了该限制。考虑使用一些dynamic memory allocation(例如使用new;但是通过使用更高级别的C++ 构造,例如containerssmart pointers,您通常应该避免显式使用它)。大多数 C++ 标准 containers,尤其是 std::vector(但不是 std::array)将它(堆)用于内部数据。

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

如果您在 Linux 上编译 with g++ -Wall -Wextra -Wstack-usage=1500 -g,编译器可能会警告您。也向use the gdb debugger学习。成为afraidundefined behavior

您还可以使用一些额外的library,例如提供矩阵的Boost(或其他东西),或者拥有自己的Matrixabstract data type(将堆分配其数据)。注意rule of 5

花几周时间阅读一些好的 C++ programming book,但请注意,C++ 是一种非常困难和复杂的编程语言(因此请阅读 SICP 以了解更多通用编程概念并使用一些Scheme 实现,例如Racket)。稍后,您可以在Garbage collection 上阅读一些book(其中的概念与memory management 有关)。

【讨论】:

  • 多么好的解释,谢谢。你能给我一些参考资料(书籍、网站、课程),让我了解内存管理中的基本主题吗?
  • 我添加了更多参考。你首先需要学习C++编程
【解决方案2】:

您遇到了堆栈溢出。

sizeof(double) 在 Windows 上为 8。

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

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

【讨论】:

  • 谢谢老兄,你是对的,确实知道
【解决方案3】:

您可能试图在堆栈上分配数组,而在 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 比守卫对象的寿命更长。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    • 2019-05-25
    • 2017-03-28
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    相关资源
    最近更新 更多