- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用 setrlimit 调整堆栈大小后,我在堆栈上分配了一个大数组。当这个数组在 main() 中声明,然后作为参数传递给方法时,我收到段错误。当数组在方法内声明为局部变量时,代码运行时不会出现任何段错误。我正在具有 8GB RAM 的 Amdx86-64 Linux 机器上运行代码。
#include <iostream>
#include <sys/resource.h>
using usll = unsigned long long;
void sumArray0();
double sumArray1(double c[], usll dim);
int main(int argc, char* argv[])
{
const rlim_t stackSize = 3 * 1024UL * 1024UL * 1024UL;
struct rlimit rl;
int result;
printf("The required value of stackSize is %lu\n", stackSize);
result = getrlimit(RLIMIT_STACK, &rl);
if (result == 0)
{
if (rl.rlim_cur < stackSize)
{
rl.rlim_cur = stackSize;
result = setrlimit(RLIMIT_STACK, &rl);
if (result != 0)
{
fprintf(stderr, "setrlimit returned result = %d\n", result);
}
else
{
printf("The new value of stackSize is %lu\n", rl.rlim_cur);
}
}
}
// // This seg faults
// const usll DIM = 20000UL * 18750UL;
// double c[DIM];
// for (usll i{}; i<DIM; ++i)
// {
// c[i] = 5.0e-6;
// }
// double total = sumArray1(c, DIM); // Seg fault occurs here
sumArray0(); // This works
std::cout << "Press enter to continue";
std::cin.get();
return 0;
}
void sumArray0()
{
double total{};
const usll DIM = 20000UL * 18750UL;
double c[DIM];
for (usll i{}; i<DIM; ++i)
{
c[i] = 5.0e-6;
}
for (usll i{}; i<DIM; ++i)
{
total += c[i];
}
std::cout << "Sum of the elements of the vector is " << total << std::endl;
}
double sumArray1(double c[], usll dim)
{
double total{};
for (usll i{}; i<dim; ++i)
{
total += c[i];
}
return total;
}
我的问题是:
为什么我在第一种情况下会出现 stackoverflow?
是因为调用方法 sumArray1() 时请求了新的内存块吗?
当作为参数传递给方法时,数组不是通过指针访问的吗?
正如此处推荐的,Giant arrays causing stack overflows ,我总是使用 std::vector 并且从不在堆栈上分配大数组以防止出现上述问题。如果有人知道可以使 sumArray1() 调用正常工作的任何调整、技巧或解决方法,我将非常感激。
最佳答案
所以在我看来,您正在编译时没有启用优化,因为否则 main
中的数组将被完全优化,因为用它完成的计算永远不会以任何可观察的方式使用。 (这确实对任何事情都不好。即使出于调试目的,您也应该使用 -Og
。)
在评论中您提到您正在使用 -fPIC
标志进行编译。这可以防止 gcc 内联 sumArray1 调用,从而无论优化标志如何,都无法对数组进行优化。您可能应该使用 -fpie
(这可能已经是默认值)作为可执行文件,而不是 -fPIC
,后者适用于共享库,并且会带来这些性能损失,请参阅还有here和 here .
如果是这种情况,那么回答你的问题:问题不在于传递给函数。问题在于,堆栈空间是在进入函数时分配的,因此是在设置限制之前分配的。
现在,这里的“分配”仅意味着修改堆栈指针,但很可能在设置限制之前,main
访问此堆栈帧中的任何位置。特别是,编译器可以根据需要重新排序堆栈帧中变量的位置,或者可能根据您的编译器设置等添加堆栈保护。
在设置限制之前进行任何此类访问都会导致段错误。
请注意,编译器也可以自由内联函数。因此,如果编译器决定内联该函数调用,即使在 sumArray0
中执行操作也可能会给您带来麻烦,因为这样该数组将成为 main
堆栈框架的一部分与上面讨论的问题相同。
编译器可能会认识到内联具有大堆栈帧的函数存在潜在危险,因此不会这样做,但您需要在编译器文档中检查这一点。
无论如何,编译器和操作系统都不希望程序使用大的堆栈帧。那不是他们的目的。堆/空闲存储专门用于处理比通常堆栈帧更大的内存分配。通常最好的做法是启用大型堆栈帧的警告并注意它们。
关于c++ - 将大型堆栈分配数组作为函数参数传递会导致堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59273563/
出于好奇 - 我知道有 LAMP - Linux、Apache、MySQL 和 PHP。但是还有哪些其他 Web 堆栈替代方案的缩写呢?像 LAMR - Linux、Apache、MySQL Ruby
我有以下代码。 var stackMapIn = []; var stackMapOut = []; var stackBack = []; stackMapOut.push("m1"); $scop
我遇到了导致我的堆栈无法恢复的情况,我别无选择,只能将其删除。使用完全相同的模板,我继续创建了另一个同名的堆栈。 The following resource(s) failed to create:
这是我第一次查看 Node 堆栈,自从我学习使用 Ruby on Rails 进行 Web 开发以来,我对一些基本的东西有点困惑。我了解 Rails 目录是什么样的。 demo/ ..../app .
本文实例讲述了C语言使用深度优先搜索算法解决迷宫问题。分享给大家供大家参考,具体如下: 深度优先搜索 伪代码 (Pseudocode)如下: ?
我正在按照指南 here ,它告诉我: The stack setup will download the compiler if necessary in an isolatedlocation (
同时 trying to debug a different question ,我安装了一个似乎与我安装的其他一些软件包冲突的软件包。 我跑了 $ stack install regex-pcre-
我花了几个小时创建了一个方法,该方法将从堆栈 s1 中获取 null 元素,并将它们放入 s2 中。然后该类应该打印堆栈。方法如下 import net.datastructures.ArraySta
我有一个类Floor,它有一个Stack block ,但我不知道如何初始化它。我曾尝试过这样的: public class Floor { private Stack stack;
我知道这个问题已经问过很多次了,但搜索一个小时后我仍然遇到问题。 我想使用一个 lifo 堆栈,它可以存储最大数量的元素。达到最大数量后,首先删除该元素并将其替换为新元素,这样在第一次弹出时我可以获取
我需要编写一个方法,压缩以执行以下操作; 目标compress方法是从栈s1中移除所有null元素。剩余(非空)元素应按其初始顺序保留在 s1 上。辅助堆栈 s2 应用作s1 中元素的临时存储。在该方
我正在尝试验证以下代码发生的顺序。 function square(n) { return n * n; } setTimeout(function(){ console.log("H
我需要一个字符数组,其中包含基于特定文件夹中文件数量的动态数量的字符数组。我能够通过初始化 char (*FullPathNames)[MAX_FILENAME_AND_PATHNAME_LENGTH
我正在编写一些日志逻辑并想要进行一些缩进。了解是否存在任何函数调用或某个函数是否已完成的最简单方法是查看堆栈/帧的当前地址。让我们假设堆栈颠倒增长。然后,如果 log() 调用中的堆栈地址小于前一次调
所以内存分段在x86-64中被放弃了,但是当我们使用汇编时,我们可以在代码中指定.code和.data段/段,并且还有堆栈指针寄存器。 还有堆栈段、数据段和代码段寄存器。 代码/数据/堆栈的划分是如何
void main() { int x = 5; // stack-allocated Console.WriteLine(x); } 我知道 x 是堆栈分配的。但是关于 x 的堆栈中
这是我关于 SO 的第一个问题。这可能是一个愚蠢的问题,但到目前为止我还没弄明白。 考虑下面的程序 Reader.java: public class Reader { public
java中有没有一种快速的方法来获取嵌套/递归级别? 我正在编写一个函数来创建组及其成员的列表。成员也可以是团体。我们最终可能会得到一组循环的组/成员。 我想在某个任意级别停止。 我知道我可以将变量保
考虑以下代码: struct A{...}; A a[100]; A* pa = new A[100]; delete[] pa; a/pa 元素的销毁顺序是由标准定义的还是实现定义的(对于第二种情况
我在下面有一些代码。此代码是一个基本的压入/弹出堆栈类,我将其创建为模板以允许某人压入/弹出堆栈。我有一个家庭作业,我现在要做的是创建一个具有多个值的堆栈。 所以我希望能够创建一个基本上可以发送三个整
我是一名优秀的程序员,十分优秀!