我想为某个大小(比如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放在内存段末尾的一些信息,比如大小信息或其他信息。
有人了解这个问题吗?非常感谢。
--Mitchell
编辑:我发现问题了。这是一个字节顺序问题,我甚至没有在最初的帖子中提到。当然,在我发布到Stack Overflow的五分钟后,我自己解决了这个问题!我应该删除这篇文章吗?正如你们所指出的,这个问题并不是由malloc引起的。谢谢你的回复。
您在(char*) my_struct + STRUCT_SIZE
上调用free()吗?你不能那样做。free需要malloc返回的指针,而不是指针的某个偏移量。
你可以简单地通过memcpy覆盖该数据-不要释放它。如果你想释放它,你还需要释放结构。
您可能想做的是在结构中添加一个void*字段,然后malloc/free它。结构的用户会认为它是不透明的,您可以在内部处理中做任何需要做的事情。
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);
您似乎想要一个末尾带有可变长度数组的结构,如:
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);
是什么导致了错误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)