首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >&address + sizeof(type)和&address + 1有什么区别?

&address + sizeof(type)和&address + 1有什么区别?
EN

Stack Overflow用户
提问于 2018-12-15 00:52:59
回答 2查看 81关注 0票数 0

我正在尝试重新编写malloc函数。

假设我们有一个这样的结构:

代码语言:javascript
复制
typedef struct      s_block
{
    char            is_free;
    size_t          size;
    struct s_block  *next;
    void            *memory;
}                   t_block;

我使用mmap分配了一页内存,并将其转换为一个大的t_block。

然后,我有一个大小为4064的块(4096 -大小为t_block)。

例如,如果我将我的malloc命名为12号,下面是我要做的:

代码语言:javascript
复制
block->next = &block + 1 + size // Setting the next block
block->next->size = block->size - size - sizeof(t_block); // 4064 - 12 - 32
block->size = size; // 12
block->is_free = NOT_FREED;
block->memory = &block + 1;
block->next->memory = &(block->next) + 1;
block->next->next = NULL;
block->next->is_free = FREE;

当我使用+1或+ sizeof(t_block)时,我经常会遇到问题。那么,这两者的区别是什么呢?

代码语言:javascript
复制
block->next = &block + 1 + size;

和:

代码语言:javascript
复制
block->next = &block + sizeof(t_block) + size;
EN

回答 2

Stack Overflow用户

发布于 2018-12-15 01:10:29

假设block被声明为t_block *,并且您希望这个块和下一个块之间有size字节,那么这两个都不是您所期望的。因为&block是指针的地址,所以对它执行的任何指针运算都是基于指针的大小,而不是结构的大小。

你真正想要的是:

代码语言:javascript
复制
block->next = (t_block *)((char *)block + sizeof(t_block) + size);

通过首先将block转换为char *,在其上执行的任何指针运算都适用于单个字节,而不是结构大小的倍数。因此,我们从块的地址开始,向上移动sizeof(t_block)字节到用户内存的开始,然后size更多的字节到该内存的末尾和下一个块的开始。

此外,由于结构的对齐要求,您需要确保下一个块正确对齐。您可以按如下方式执行此操作:

代码语言:javascript
复制
size_t block_align = (sizeof(t_block) - (size % sizeof(t_block))) % sizeof(t_block);
block->next = (t_block *)((char *)block + sizeof(t_block) + block_align + size);
票数 2
EN

Stack Overflow用户

发布于 2018-12-15 01:01:37

((Type*)(p)) + n == ((char*)(p)) + sizeof(Type)*n

类型化指针上的算术运算(即真正的加/减)根据指向类型的大小进行缩放(sizeof(char)被定义为1)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53783904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档