首页 文章

重新分配内存时“无效的下一个大小”异常

提问于
浏览
1

P.S.: 我几乎有"invalid next size"的所有问题,但他们没有帮助我,因为我没有另外一段代码可以使用malloc或realloc,所以这是排除在外的 . 另外,我没有超出内存空间的限制,所以我也很好 .

我有以下代码给我 - *** Error in ./server_issue':realloc():下一个大小无效:0x08249170 ***` .

我无法识别问题,我一次只分配64个字节,所以我没有内存地址空间,还有其他内存分配可能会损坏我的堆内存 .

错误说,下一个大小无效但我的上一个日志告诉 Reallocating 64 bytes, Aborted (core dumped) 所以这意味着我仍然在尝试分配64个字节 . 那么,为什么错误呢?

对于HTML文件,任何超过256个字节的文件 .

Code: (重现问题的最小代码)

#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;
}

Output:

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

Update: 即使我分配64个字节而不是使用 readBytesrealloc 然后我也得到相同的错误 . 因为这条线我收到错误 - *content = realloc(*content, readBytes);

1 回答

  • 5

    另外,我没有超出内存空间的限制,所以我也很好 .

    过度确定代码是使调试更加困难的好方法 . 怀疑一切都错了 .


    You're not allocating enough memory, because you're using realloc incorrectly.

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

    每次循环时,您都要传递 readBytes ,这是您要复制的其他字节数 . 所以你的缓冲区从未增长 . 但是接下来你要写完它的结尾:

    memcpy(*content + totalLength, ...
    

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


    在这样的循环中调用 realloc 在性能方面通常是一个坏主意 . 您应该预先分配足够的总空间,然后在循环中读入它 .

    要获得总文件大小:

    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;
    }
    

    Output:

    $ 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() 返回相同的值,即使多次调用 realloc 后,它们也会传递相同的大小 . 此外,即使我们分配了16个字节,它返回24的事实也是预期的,并且是分配器的实现细节的结果 .

    malloc_usable_size 的手册页:

    注意由于对齐和最小大小限制,malloc_usable_size()返回的值可能大于请求的分配大小 . 虽然应用程序可以覆盖多余的字节而没有不良影响,但这不是一个好的编程习惯:分配中的多余字节数取决于底层实现 . 该函数的主要用途是用于调试和内省 .

相关问题