C 了解内存分配、测试程序崩溃

C 了解内存分配、测试程序崩溃,c,C,我刚读完K&R,这就是我所知道的全部C。我所有的编译都是使用MinGW从Windows命令行完成的,我对高级调试方法一无所知(因此在我下面的第二个程序中出现了“ghetto debug”注释) 我正在尝试制作一些小的测试程序来帮助我更好地理解内存分配是如何工作的。前两个程序不使用malloc或free,我只是想看看如何为函数本地的标准数组分配和取消分配内存。我的想法是观察我正在运行的进程的RAM使用情况,看看它是否符合我的理解。对于下面的第一个程序,它确实像我预期的那样工作。alloc\u on

我刚读完K&R,这就是我所知道的全部C。我所有的编译都是使用MinGW从Windows命令行完成的,我对高级调试方法一无所知(因此在我下面的第二个程序中出现了“ghetto debug”注释)

我正在尝试制作一些小的测试程序来帮助我更好地理解内存分配是如何工作的。前两个程序不使用malloc或free,我只是想看看如何为函数本地的标准数组分配和取消分配内存。我的想法是观察我正在运行的进程的RAM使用情况,看看它是否符合我的理解。对于下面的第一个程序,它确实像我预期的那样工作。
alloc\u one\u meg()
函数分配并初始化250000个4字节整数,但该MB会在函数返回时立即取消分配。因此,如果我连续调用该函数1000000次,我将永远不会看到我的RAM使用率超过1MB。而且,它是有效的

#include <stdio.h>
#include <stdlib.h>

void alloc_one_meg() {
    int megabyte[250000];
    int i;
    for (i=0; i<250000; i++) {
        megabyte[i] = rand();
    }
}

main()
{
    int i;
    for (i=0; i<1000000; i++) {
        alloc_one_meg();
    }
}
#包括
#包括
无效alloc_one_meg(){
整数兆字节[250000];
int i;

对于(i=0;i,您遇到了堆栈溢出

本地自动存储变量(如
megabyte
)在空间有限的堆栈上分配。malloc在堆上分配,允许更大的分配

您可以在此处阅读更多内容:


(我应该注意,C语言没有指定内存分配的位置-堆栈和堆是实现细节)Windows程序中堆栈的大小通常在1MB左右,因此在第二次递归时,堆栈溢出。不应该在堆栈上分配如此大的数组,请使用
malloc
free
分配和释放堆上的内存(对于这样大小的数组,无法绕过
malloc
):

void alloc\u one\u meg(){
int*megabyte=malloc(sizeof(int)*250000);//为250000分配空间
//堆上的整数
int i;

对于(i=0;iStackOverflow。这是一个技巧性问题吗?

通过递归函数调用分配的内存是从堆栈中分配的。所有堆栈内存必须是连续的。当进程启动线程时,Windows将为该线程的堆栈保留一定范围的虚拟内存地址空间。要重新分配的内存量服务是在EXE文件的“PE头”中指定的。PE代表“可移植可执行文件”

使用Visual Studio附带的
dumpbin
实用程序,将其自身(
dumpbin.exe
)作为输入文件:

dumpbin/headers dumpbin.exe

…有一些输出,然后:

      100000 size of stack reserve
        2000 size of stack commit
“100000”是一个十六进制数,等于1048576,因此表示大约1MB

换句话说,操作系统将只为堆栈保留1MB地址范围。当该地址范围用完时,Windows可能或可能无法分配更多的连续内存范围以增加堆栈。结果取决于是否有更多的连续地址范围可用。由于到线程开始时所做的其他分配窗口


要在Windows下分配最大数量的虚拟内存,请使用
VirtualAlloc
函数系列。

多酷啊,我在stackoverflow.com上了解了堆栈溢出。我应该在meta上发布此消息!感谢您的解释和链接。malloc()没有更大的空间量——请参阅dumpbin的输出和为“heap”保留的空间量他说他不想使用malloc/free。这一系列测试的一个更大的目的是帮助我理解malloc和free的用途。我想先在没有它们的情况下运行一些测试,然后用它们运行一些测试。我知道局部堆栈变量的寿命与函数enter/exit相关,而堆变量的寿命与mall相关oc/free,但我没有意识到堆栈有这么小的限制。所以我已经从这个测试中学到了一件大事。:-@Johnson是的,这是一件值得学习的事情。与堆相比,堆栈非常小,这就是为什么在得到堆栈之前不能递归很远(即使没有太多局部变量)overflow@Seth卡内基——马洛克而free()也同样有限——在使用默认值编译的二进制文件上查看dumpbin的输出。他也不能使用它们。他不能使用的是VirtualAlloc()。@Johnson这是同样的事情,请参见(忽略关于“道德等价物”一词真正含义的愚蠢辩论)这表明
malloc
VirtualAlloc
之间几乎没有什么区别。不,我只是一个noob。我很快就了解到,有很多关于C的东西我需要知道,但我无法从K&R那里得到(正如我所说,我目前为止唯一的知识来源).哪里是一个学习知识的好地方,这些知识会阻止我提出这样的问题?堆栈/堆,诸如此类的东西(这些概念在K&R中不存在,我知道为什么).现在你有了一个堆栈溢出崩溃,你对内存有了更好的理解。事情的发展很有趣。是的,我对编程很陌生,但对测试的想法并不陌生。我是一名工程师,也是一个软件的重度用户,我很清楚打破东西是理解它们的最好方式!:-)
void alloc_one_meg() {
    int *megabyte = malloc(sizeof(int) * 250000); // allocate space for 250000
                                                  // ints on the heap
    int i;
    for (i=0; i<250000; i++) {
        megabyte[i] = rand();
    }
    j++;
    printf("Loop %d\n", j); // ghetto debug
    if (j<1000) {
        alloc_one_meg();
    }

    free(megabyte); // DO NOT FORGET THIS
}
      100000 size of stack reserve
        2000 size of stack commit