C语言 在void*中使用指针算术



我的机器是ubuntu 20.04

我有一份作业说使用系统调用(mmap和munmap)实现您自己的动态内存分配函数:mymalloc和myfree,它们具有与标准C库中的malloc和free相同的功能。将实现保存在mymalloc.h和mymalloc .">

文件中然后它说我们必须至少分配所需的长度+用于存储的变量的大小长度(size_t)。我们将长度存储为第一个元素,然后返回下一个元素。">

这是我的代码(size是size_t类型的参数)

size_t total_size = size + sizeof(size_t);
size_t allocation_overflow = total_size % page_size;
if(allocation_overflow > 0)
total_size += page_size - allocation_overflow;
void *data = mmap(NULL ,total_size, PROT_EXEC | PROT_READ | PROT_WRITE , MAP_PRIVATE , 0 , 0);
// size_ptr will point to stored size
size_t *size_ptr =(size_t *)data;
size_ptr[0] = total_size;

// pointer to allocated memory
void* allocated_mem_pointer = data + sizeof(size_t);

并给出警告"指针类型'void*'用于算术[-Wpointer arith]">

必须将长度存储在第一个元素中,因为赋值说明了这一点,但我不警告我想编写干净的代码。İS这是合法的。我已经读指针算术时,void有未知的大小但是我找不到解决它的答案。

正如你所发现的,你不能用void*做算术,除非你使用GCC扩展或类似的。

简单的解决方案是:不要使用void*

在你的代码中已经有

// size_ptr will point to stored size
size_t *size_ptr =(size_t *)data;
size_ptr[0] = total_size;

现在要计算计数器头后面的地址。

arr[0]后面的元素就是arr[1]

使用此命令获取来电者的地址:

// pointer to allocated memory
void* allocated_mem_pointer = &size_ptr[1];

当你想回到你的myfree函数头,你可以做类似的技巧:

void myfree(void*addr) {
size_t *buff = (size_t*) addr;
size_t header = buff[-1];
// ... 
}

这是有效的,因为buff[-1]指向最初在myalloc函数中分配的相同内存对象。

注意:

如果您要创建的函数不仅用于教育目的,您还需要处理返回给调用者的地址的正确对齐。

当您使用指针算术(ie add a number to pointer)时,您需要正确键入指针:

IntPointer32Bits + 1 => will give the address of the next adjacent 32 bits integer
IntPointer16Bits + 1 => will give the address of the next adjacent 16 bits integer

指针运算的结果地址取决于指针类型。

void* allocated_mem_pointer = data + sizeof(size_t);

在这种情况下,datavoid *,所以指针运算对编译器来说不清楚(需要计算下一个8 bits,next 16 bitsnext 32 bits?)你不应该使用void *,但你应该有一个真正的类型,我假设uint8_t

size_t total_size = size + sizeof(size_t);
size_t allocation_overflow = total_size % page_size;
if(allocation_overflow > 0)
total_size += page_size - allocation_overflow;
uint8_t *data = mmap(NULL ,total_size, PROT_EXEC | PROT_READ | PROT_WRITE , MAP_PRIVATE , 0 , 0);
// size_ptr will point to stored size
size_t *size_ptr =(size_t *)data;
size_ptr[0] = total_size;

// pointer to allocated memory
uint8_t *allocated_mem_pointer = data + sizeof(size_t);

在这种情况下,你的意图对编译器来说是非常清楚的:allocated_mem_pointer是由uint8_t组成的内存区域,计算出的地址是data的基址,偏移量为size_t字节。(运算符sizeof返回的字节数即uint8_t)

处理void*时,对char*unsigned char*指针进行算术处理。

void *allocated_mem_pointer = (char*)data + sizeof(size_t);

相关内容

  • 没有找到相关文章

最新更新