"invalid next size" 重新分配内存时出现异常

"invalid next size" exception while reallocing memory

P.S.: 我有几乎所有关于 "invalid next size" 的问题,但他们没有帮助我,因为我没有其他问题哪段代码是malloc还是realloc,这样就排除了。另外,我没有分配超出内存限制 space 所以我在这方面也很好。

我有下面的代码给我 - *** Error in./server_issue': realloc(): invalid next size: 0x08249170 ***`.

我无法确定问题所在,我一次只分配 64 个字节,所以我没有用完内存地址 space 并且还有其他内存分配可能损坏了我的堆内存.

错误说,下一个大小无效,但正如我上一个日志所说 Reallocating 64 bytes, Aborted (core dumped) 所以这意味着我仍在尝试分配 64 字节。那么,为什么会出错?

对于HTML文件,有任何超过256字节的文件。

代码:(重现问题的最少代码)

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

typedef char BYTE;
bool load(FILE*, BYTE**, size_t*);

int main(void)
{
    FILE* file = fopen("/home/university/psets/pset6/pset6_working/public/hello.html", "r");
    BYTE* content;
    size_t length;
    load(file, &content, &length);
}

bool load(FILE* file, BYTE** content, size_t* length)
{
    int totalLength = 0;
    int readBytes = 0;
    *content = NULL;

    BYTE* fileContentTemp[64]; // working with 222222
    while ((readBytes = fread(fileContentTemp, 1, 64, file)) > 0)
    {
        printf("Reallocating %d bytes, ", readBytes);
        *content = realloc(*content, readBytes);
        printf("%p\n", *content);
        if(totalLength != 0)
        {
            memcpy(*content + totalLength + 1, fileContentTemp, readBytes);        
        } else{
            memcpy(*content + totalLength, fileContentTemp, readBytes);        
        }
        totalLength = totalLength + readBytes;
    }

    *length = totalLength;

    printf("CC image: %s\n", *content);
    printf("length is %d\n", *length);
    printf("fileContent %p\n", *content);

    return true;
}

输出:

Reallocating 64 bytes, 0x8249170
Reallocating 64 bytes, 0x8249170
*** Error in `./server_issue': realloc(): invalid next size: 0x08249170 ***
Reallocating 64 bytes, Aborted (core dumped)


更新: 即使我分配 64 个字节而不是使用 readBytesrealloc 也会出现同样的错误。由于这一行,我收到错误 - *content = realloc(*content, readBytes);

Also, I am not assigning beyond the limits of memory space so I am fine on that front as well.

对您的代码过于自信是增加调试难度的好方法。怀疑一切都是错误的。


您没有分配足够的内存,因为您使用 realloc 不正确。

p = realloc(p, n) 不会 添加 n 字节到分配,它会将总分配大小更改为您告诉它的大小。

每次通过循环时,您都会传递 readBytes,这是您要复制的 额外 字节数。所以你的缓冲区永远不会增长。但是然后你继续写到它的末尾:

memcpy(*content + totalLength, ...

因为 totalLength 在整个循环中不断增长。


像这样在循环中调用 realloc 从性能方面来说通常不是一个好主意。您应该预先分配足够的总数 space,然后在循环中读入它。

获取总文件大小:

size_t get_file_size(FILE *f)
{
    long oldpos;
    size_t result;

    // Save the original file position
    oldpos = ftell(f);

    // Seek to the first byte past the end of the file
    fseek(f, 0, SEEK_END);

    // Get the file position - the number of bytes in the file
    result = ftell(f);

    // Return the file position to where it was
    fseek(f, oldpos, SEEK_SET);

    return result;
}

这是一个测试,以证明我所说的 realloc。请注意,这通常使用 malloc_usable_size 这是不好的做法。

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

int main(void)
{
    int i;
    char *p = NULL;

    for (i = 0; i < 10; i++) {
        p = realloc(p, 16);
        printf("[%d] size: %zd\n", i, malloc_usable_size(p));
    }

    return 0;
}

输出:

$ gcc -Wall -Werror -o realloc realloc.c 
$ ./realloc 
[0] size: 24
[1] size: 24
[2] size: 24
[3] size: 24
[4] size: 24
[5] size: 24
[6] size: 24
[7] size: 24
[8] size: 24
[9] size: 24

请注意 malloc_usable_size() returns 相同的值,即使在多次调用 realloc 后传递相同的大小也是如此。此外,它 returns 24 这一事实,即使我们分配了 16 个字节也是预期的,并且是分配器实现细节的结果。

来自 malloc_usable_size 的手册页:

NOTES

The value returned by malloc_usable_size() may be greater than the requested size of the allocation because of alignment and minimum size constraints. Although the excess bytes can be overwritten by the application without ill effects, this is not good programming practice: the number of excess bytes in an allocation depends on the underlying implementation.

The main use of this function is for debugging and introspection.