我想为某个大小的结构(例如,20个字节)分配足够的内存,加上额外的字节数,比如500(这个数字是在运行时计算的,因此不能仅仅是一个额外的字段结构)。所以,我有一个看起来像这样的malloc:
some_struct *my_struct = (some_struct *) malloc (STRUCT_SIZE + MORE_BYTES);
但是,我很确定malloc只是真的为结构分配了足够的内存,因为这是我将返回值转换为的指针。
如果我尝试写到应已被malloc'd的内存...
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。谢谢你的回复。答案 0 :(得分:1)
您是否在(char*) my_struct + STRUCT_SIZE
上致电免费()?你不能这样做。 free期望malloc返回的指针,而不是指针的一些偏移量。
您可以通过memcpy简单地覆盖该数据 - 不要释放它。如果你想释放它,你也需要释放结构。
你可能想要做的是在你的struct和malloc / free中添加一个void *字段。结构的用户会认为它是不透明的,你可以做任何你需要在内部处理中做的事情。
答案 1 :(得分: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);
答案 2 :(得分: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);
答案 3 :(得分: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)