“CRT检测到应用程序在堆缓冲区结束后写入内存”的意思是什么?

18

我遇到了代码问题,它在free(q->izv)函数处中断,并出现调试错误:

CRT detected that the application wrote to memory after end of heap buffer

我不知道那是什么意思,所以我会非常感激任何帮助。

    typedef struct izvodjaci{
        char *izv;
        int broj;
        struct izvodjaci *sled;
    }IZV;

    obrisi_i(IZV *p){
        while (p){
            IZV *q;
            q = p;
            p = p->sled;
            if (!strcmp(q->izv,"UNKNOWN")) free(q->izv);
            free(q);
        }
    }

提前致谢


1
很可能这只是缓冲区溢出被检测到的地方,而不是它实际发生的地方。尝试将整个代码缩减为一个小示例,以复制该问题并在此处发布,假设您未先找到该问题。 - uesp
1个回答

40
“CRT detected that the application wrote to memory after end of heap buffer” 的意思是什么? 假设你分配了一个堆缓冲区:
char* buffer = malloc(5);

好的,buffer 现在指向堆上的五个字符。

假设你往那个缓冲区写入六个字符:

buffer[0] = 'a';
buffer[1] = 'b';
buffer[2] = 'c';
buffer[3] = 'd';
buffer[4] = 'e';
buffer[5] = '\0';

你已经破坏了堆;你只被允许写五个字符,但你写了六个。

程序现在可以执行任何事情。它可以正常工作,也可以崩溃,可以将所有密码发送给中国的黑客,任何事情

你的实现显然选择了最好的选择,即“告诉你犯了错误”。你应该非常,非常高兴这就是发生的事情,而不是任何可怕的替代方案。不幸的是,它在缓冲区被释放时通知你,而不是在你犯错误时通知你,但要高兴你收到了错误信息。


谢谢。你是对的。我计算错误,使用了比我分配的多一个空格。 - user3699827
我几乎重写了所有东西,除了那个......这是我第一次犯这个错误,所以我之前没见过那个错误信息,有点慌了。还有谢谢你的建议。 - user3699827
嗨Eric,这太神奇了。我在从src char复制到dest char时使用了strlen。你能告诉我为什么Visual Studio编译器在free期间发现了这个损坏问题,而不是在我写出内存边界之外时发现它吗? - saurabheights
1
这是一个关于实际代码的具体问题的问答网站,你提出了一个关于实际代码的具体问题,因此我鼓励你(1)搜索是否已经有答案,如果没有(2)发布一个问题! - Eric Lippert
@user1874627:话虽如此,但可以这样想:假设您正在开发一种类似于C语言的编译器。请描述一下您将如何实现您建议的功能:在写入时检测任意内存缓冲区中任意位置的越界写入。该功能不能通过“魔法”实现;您必须为其生成代码。那么这段代码会是什么样子呢?它不必在汇编代码级别上实现;尝试用高级语言来描述它。 - Eric Lippert
1
如果你开始有困难,这里有一个更简单的问题。假设你正在生成代码来检测内存缓冲区中任意偏移量处的越界写入,但你知道该偏移量是从缓冲区的开头开始计算的。在这种情况下,你会如何编写越界写入检测?这两个问题都是可以解决的,但这个问题要容易得多。 - Eric Lippert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接