编程语言书籍解释了在堆栈上创建了值类型,并且在堆上创建了引用类型,而没有解释这两者是什么.我还没有看清楚这个问题.我理解堆栈是什么.但,
language-agnostic heap stack memory-management dynamic-memory-allocation
有关堆栈分配的许多相关问题是可以理解的
但是在各种*nix机器上,我可以发出bash命令
ulimit -s unlimited
Run Code Online (Sandbox Code Playgroud)
或者csh命令
set stacksize unlimited
Run Code Online (Sandbox Code Playgroud)
这如何改变程序的执行方式?是否对程序或系统性能有任何影响(例如,为什么这不是默认值)?
如果更多的系统细节是相关的,我主要关注在x86_64硬件上运行的Linux上使用GCC编译的程序.
我正在经历其中一个主题.程序崩溃是因为它在函数内部声明了一个10 ^ 6的数组.
给出的原因是堆栈上的内存分配失败导致崩溃.
当全局声明相同的数组时,它运行良好.(堆上的内存保存了它).
现在,让我们假设,堆栈向下增长并向上堆积.
我们有:
现在,我相信如果堆栈上的分配失败,它也必须在堆上失败.
所以我的问题是:堆栈大小有限制吗?(超过限制导致程序崩溃).或者我错过了什么?
这个简单的C程序很少在相同的调用深度终止:
#include <stdio.h>
#include <stdlib.h>
void recursive(unsigned int rec);
int main(void)
{
recursive(1);
return 0;
}
void recursive(unsigned int rec) {
printf("%u\n", rec);
recursive(rec + 1);
}
Run Code Online (Sandbox Code Playgroud)
这种混乱行为背后的原因是什么?
我正在使用fedora(16GiB ram,堆栈大小为8192),并使用cc编译而没有任何选项.
编辑
问题是更多,因为在Linux上,线程堆栈大小是固定的,并且给出了ulimit -s什么会影响可用的堆栈大小,以便堆栈溢出并不总是出现在相同的调用深度?
编辑2 @BlueMoon总是在他的CentOS上看到相同的输出,而在我的Fedora上,堆栈为8M,我看到不同的输出(最后打印的整数261892或261845,或261826,或......)
在下面的代号中
#?include ?<stdio.h>
int main()
{
printf("Stack Overflow");
main();
}
Run Code Online (Sandbox Code Playgroud)
运行后,该程序编译器将打印"堆栈溢出"到栈overflow.Here我知道堆栈溢出意味着,这意味着它会打印,直到内存full.Here我的问题是它的内存是什么呢?堆栈的大小是多少?
我一直在使用 LodePNGlodepng_encode24_file对一些 24 位 RGB 图像文件进行编码,到目前为止它工作得非常好。但是,我注意到当我向它提供大于 15360*15360 像素大小的数据集时它似乎崩溃了(14336*14336 像素图像编码良好)。
对于 32 位情况(崩溃前的最大大小略低),可以通过简单地替换该行来获得此行为的最小示例
unsigned width = 512, height = 512;
Run Code Online (Sandbox Code Playgroud)
和
unsigned width = 1024*14, height = 1024*14;
Run Code Online (Sandbox Code Playgroud)
在LodePNG 的 example_encode.c 文件中,并执行它。
我之前遇到过 C 代码崩溃的问题,因为我将大数组分配到堆栈内存(其最大大小通常在 2MB 左右)而不是堆内存,所以作为 C 的新用户,我的第一直觉是看看是否有堆内存大小的上限。
但是,根据这个答案,堆内存没有限制,所以一定是其他地方出了问题。
我的第二个猜测是崩溃是由于 PNG 格式本身支持的最大图像尺寸的固有限制。但是,根据此答案及其下方的评论,PNG 支持的最大文件大小约为 4,000,000,000 * 4,000,000,000 像素,因此这也不是罪魁祸首。
有没有人猜测可能会出什么问题?其他人在尝试时是否能够重现此错误?
编辑:就 RAM 消耗而言,我有 8GB RAM,减去硬件保留的、使用中的、修改过的和备用内存(Windows 资源监视器实用程序使用的术语),在进行计算时,我有大约 4GB 的可用 RAM。对于 15000*15000 大小的 32 位图像,需要小于 1GB。同样,当我成功编码 14000*14000 24 位图像时,我的可用 RAM 在编码过程的任何时候都不会低于 3GB,所以我认为 RAM 耗尽不是问题。