首页 文章

Malloc没有分配尽可能多的内存(我相信)[关闭]

提问于
浏览
-2

我想为某个大小的结构(例如,20个字节)分配足够的内存,加上额外的字节数,比如500(这个数字是在运行时计算的,因此不能简单地是结构的附加字段) ) . 所以,我有一个看起来像这样的malloc:

some_struct *my_struct = (some_struct *) malloc (STRUCT_SIZE + MORE_BYTES);

但是,我很确定malloc只是为结构分配了足够的内存,因为这是我将返回值转换为的指针 .

如果我试着写入应该是malloc的内存...

memcpy(((char *) my_struct) + STRUCT_SIZE, ptr_to_some_data, MORE_BYTES);

...然后尝试释放该内存,我收到以下错误:

*** glibc detected *** ./my_program: free(): invalid next size (fast): 0x09b6d3f0 ***

我相信这是因为我复制到堆内存后半部分的数据覆盖了malloc放在内存段末尾的一些信息,比如大小信息等等 .

有没有人对这个问题有所了解?非常感谢 .

  • 米切尔

编辑:我发现了问题 . 这是一个字节顺序问题,我在原帖中没有提到 . 当然,在我发布Stack Overflow五分钟后,我自己解决了这个问题!我应该继续删除这篇文章吗?正如大家所指出的那样,问题不在于malloc . 谢谢你的回复 .

4 回答

  • 1

    你在 (char*) my_struct + STRUCT_SIZE 上调用free()吗?你不能这样做 . free期望malloc返回的指针,而不是指针的一些偏移量 .

    您可以通过memcpy简单地覆盖该数据 - 不要释放它 . 如果你想释放它,你也需要释放结构 .

    你可能想要做的是在你的struct和malloc / free中添加一个void *字段 . 该结构的用户会认为它是不透明的,您可以在内部处理中执行任何操作 .

  • 1

    malloc分配您请求分配的空间 . 将它转换为您想要的类型不会告诉malloc它应该分配多少 . 我认为你的问题是 memcpy . 你对 char* 的演员应该是这样的:

    memcpy(((char *) my_struct) + STRUCT_SIZE, ptr_to_some_data, MORE_BYTES);
    

    而不是这个:

    memcpy((char *) my_struct + STRUCT_SIZE, ptr_to_some_data, MORE_BYTES);
    
  • 0

    看起来你想在结尾处有一个带有可变长度数组的结构,比如:

    struct my_struct {
        int some_field;
        char some_data[variable_size];
    };
    

    你这样做,不需要做指针计算:

    struct my_struct {
        int some_field;
        char some_data[0];
    };
    
    struct my_struct *foo;
    foo = malloc(sizeof(struct my_struct) + MORE_BYTES);
    memcpy(foo->some_data, ptr_to_some_data, MORE_BYTES);
    
  • 0

    是什么给出了错误 free(my_struct) ?它不应该 .

    您是否知道可以使用 foo[] 作为结构的最后一个字段,以允许您在结构结束之后访问数据?

    $ cat a.c
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    typedef struct {
       size_t size;
       char   data[];
    } packet_t;
    
    int main() {
       const char* some_data = "abc";
       size_t size = strlen(some_data)+1;
    
       packet_t* packet = (packet_t*)malloc(sizeof(packet_t) + size);
       packet->size = size;
       memcpy(packet->data, some_data, size);
    
       free(packet);
       return 0;
    }
    

    valgrind 下的输出:

    $ gcc -Wall -g -o a a.c && valgrind a
    ==11153== Memcheck, a memory error detector
    ==11153== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
    ==11153== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
    ==11153== Command: a
    ==11153== 
    ==11153== 
    ==11153== HEAP SUMMARY:
    ==11153==     in use at exit: 0 bytes in 0 blocks
    ==11153==   total heap usage: 1 allocs, 1 frees, 8 bytes allocated
    ==11153== 
    ==11153== All heap blocks were freed -- no leaks are possible
    ==11153== 
    ==11153== For counts of detected and suppressed errors, rerun with: -v
    ==11153== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 7)
    

相关问题