假设我有一块内存:
void *block = malloc(sizeof(void *) + size);
如何设置指向块开头的指针,同时仍能访问剩余的保留空间?出于这个原因,我不想简单地将'block'分配给另一个指针或NULL。
答案 0 :(得分:4)
如何将块的前两个字节设置为NULL或将其指向某个位置?
除非您在16位计算机上运行,否则这没有任何意义。
根据您调用malloc()
的方式,您计划让前N个字节成为指向其他内容的指针(其中N可能是2,4或8,具体取决于您是否'重新运行在16位,32位或64位架构上。这是你真正想做的吗?
如果是,那么你可以创建一个指针到指针的方法(认识到你实际上不能使用void *来改变任何东西,但我不想通过引入真实来混淆事物型):
void** ptr = block;
但是,用结构定义块会更加优雅(这可能包含语法错误;我没有通过编译器运行它):
typedef struct {
void* ptr; /* replace void* with whatever your pointer type really is */
char[1] data; } MY_STRUCT;
MY_STRUCT* block = malloc(sizeof(MY_STRUCT) + additional);
block->ptr = /* something */
答案 1 :(得分:2)
memset(block, 0, 2);
memset可以在string.h
答案 2 :(得分:1)
将分配的内存块的前两个字节设置为0很容易。有很多方法可以做到,例如:
((char*)block)[0] = 0;
((char*)block)[1] = 0;
现在,提问的方式显示出一些误解。
您可以在分配的块的前两个字节中放置任何内容,它不会更改任何内容以访问以下字节。唯一的区别是C字符串操作运算符用作字符串以0字节结尾的约定。然后,如果您执行strcpy((char*)block, target)
之类的操作,如果第一个字节为零,它将立即停止复制。但你仍然可以做strcpy((char*)block+2, target)
。
现在,如果你想将指针存储在块的开头(通常不是2个字节)。 您可以执行与上面相同的操作,但使用void *而不是char。
((void**)block)[0] = your_pointer;
您可以根据需要访问剩余的块,只需获取它的地址然后继续。你可以用例如。
来做void * pointer_to_rest = &((void**)block)[1];
PS:我不推荐这样的指针游戏。它们非常容易出错。你最好的举动可能是遵循@Anon提出的struct方法。
答案 3 :(得分:0)
void *block = malloc(sizeof(void *) + size); // allocate block
void *ptr = NULL; // some pointer
memcpy(block, &ptr, sizeof(void *)); // copy pointer to start of block
答案 4 :(得分:0)
我猜你要问的是什么,但你的措辞太混乱了,以至于我可能完全错了。我假设你想要一个指向你分配的块的“前2个字节”的指针,然后是另一个指向块其余部分的指针。
指针不带有关于它们指向的内存块大小的信息,因此您可以这样做:
void *block = malloc(sizeof(void *) + size);
void *first_two_bytes = block;
void *rest_of_block = ((char*)block)+2;
现在,first_two_bytes
指向您分配的块的开头,您应该将其视为指向2个字节长的内存区域。
并且rest_of_block
指向从3个字节开始的块的部分,你应该将它视为指向比你分配的字节小2个字节的内存区域。
但请注意,这仍然只是一次分配,您应该只free
block
指针。如果你释放所有三个指针,你将破坏堆,因为你将在同一个块上多次调用free
。
答案 5 :(得分:0)
在使用哈希表实现map接口时,我遇到了类似的问题,其中每个键值对(两者都不是静态大小,省略了定义编译时结构的选项)必须存储在块中堆内存,还包括指向链表中下一个元素的指针(如果在多个哈希值被散列到哈希表数组中的同一索引的情况下,则应该将这些块链接起来)。在块的开头留下指针的空间,我发现了kriss提到的解决方案:
((void**)block)[0] = your_pointer;
将指针作为数组转换为块,然后使用括号语法处理指针算术和解除引用,这是将新值复制到此指针的最干净的解决方案"字段"块。