在C中不使用malloc(使用sbrk或brk)将局部变量保存在堆上
我有一个结构如下:在C中不使用malloc(使用sbrk或brk)将局部变量保存在堆上,c,linux,unix,operating-system,C,Linux,Unix,Operating System,我有一个结构如下: struct __attribute__((__packed__)) // compiler directive, avoid "gcc" padding bytes to struct meta_data { size_t size; // 8 bytes (in 64-bit OS) char free; // 1 byte ('f' or 'o') }; 结构的大小为9字节 我想使用sbrk
struct
__attribute__((__packed__)) // compiler directive, avoid "gcc" padding bytes to struct
meta_data {
size_t size; // 8 bytes (in 64-bit OS)
char free; // 1 byte ('f' or 'o')
};
结构的大小为9字节
我想使用sbrk或brk在堆上分配9个字节,在堆上保存一个结构,并返回指向堆上动态分配的内存块的指针
目前我有这样的想法:
void *add(size_t size) {
void* returnPointer;
returnPointer = sbrk(9);
struct meta_data newMetadata;
newMetadata.size = size;
newMetadata.free = 'o';
return returnPointer;
}
此函数应该能够多次用于在堆上添加更多元数据块
但是,在这种情况下,当函数结束时,在函数内声明的局部变量newMetadata也会终止
如何将其保留在堆中,而不丢失对创建的新元数据的访问
注意:我不允许为此使用malloc。通常的方法是模仿一些
malloc
包所做的。也就是说,将元数据放在比作为“数据”指针返回的地址更低的地址
以下是重构代码以实现此目的:
#include <unistd.h>
struct meta_data {
size_t size; // 8 bytes (in 64-bit OS)
char free; // 1 byte ('f' or 'o')
// compiler directive, avoid "gcc" padding bytes to struct
} __attribute__ ((__packed__));
void *
add(size_t size)
{
struct meta_data *meta;
void *returnPointer;
meta = sbrk(sizeof(struct meta_data) + size);
meta->size = size;
meta->free = 'o';
returnPointer = meta;
returnPointer += sizeof(struct meta_data);
return returnPointer;
}
#包括
结构元数据{
size\u t size;//8字节(在64位操作系统中)
无字符;//1字节('f'或'o')
//编译器指令,避免将字节“gcc”填充到结构
}_uuu属性_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;
空虚*
添加(大小)
{
结构元数据*meta;
void*returnPointer;
meta=sbrk(sizeof(struct meta_data)+size);
元->大小=大小;
元->自由='o';
returnPointer=meta;
returnPointer+=sizeof(结构元数据);
返回指针;
}
请注意,大多数malloc
替换将保证returnPointer
为“出于任何目的对齐”,这通常意味着对齐到8字节边界(即returnPointer
的低3位为0)
上面的代码不能做到这一点,因此您可以[稍后]添加它。通常的方法是模仿一些
malloc
包所做的。也就是说,将元数据放在比作为“数据”指针返回的地址更低的地址
以下是重构代码以实现此目的:
#include <unistd.h>
struct meta_data {
size_t size; // 8 bytes (in 64-bit OS)
char free; // 1 byte ('f' or 'o')
// compiler directive, avoid "gcc" padding bytes to struct
} __attribute__ ((__packed__));
void *
add(size_t size)
{
struct meta_data *meta;
void *returnPointer;
meta = sbrk(sizeof(struct meta_data) + size);
meta->size = size;
meta->free = 'o';
returnPointer = meta;
returnPointer += sizeof(struct meta_data);
return returnPointer;
}
#包括
结构元数据{
size\u t size;//8字节(在64位操作系统中)
无字符;//1字节('f'或'o')
//编译器指令,避免将字节“gcc”填充到结构
}_uuu属性_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;
空虚*
添加(大小)
{
结构元数据*meta;
void*returnPointer;
meta=sbrk(sizeof(struct meta_data)+size);
元->大小=大小;
元->自由='o';
returnPointer=meta;
returnPointer+=sizeof(结构元数据);
返回指针;
}
请注意,大多数malloc
替换将保证returnPointer
为“出于任何目的对齐”,这通常意味着对齐到8字节边界(即returnPointer
的低3位为0)
上面的代码不能做到这一点,因此您可以[稍后]添加它。将
newMetadata
设置为指针,并将其指向sbrk
返回的新内存。只有malloc实现才允许使用非零参数调用sbrk
。除非您正在编写一个完整的malloc实现,否则请改为使用mmap
(如果这是一个家庭作业,而不是编写一个完整的malloc实现的作业,并且您被特别告知要使用sbrk
,那么该作业有问题,您可以告诉您的讲师我是这么说的。)(附录:除了sbrk
本身之外,任何人都不允许呼叫brk
。)将newMetadata
设为指针,并使其指向由sbrk
返回的新内存。只有malloc实现才允许使用非零参数调用sbrk
。除非您编写的是完整的malloc实现,否则使用mmap
执行此操作。(如果这是一项家庭作业,而不是编写一个完整的malloc实现的作业,并且你被特别告知要使用sbrk
,那么这个作业是有问题的,你可以告诉你的老师我是这么说的。)(增编:除了sbrk
本身之外,任何人都不允许调用brk
。)returnPointer+=…
应该避免,因为C没有在void*
上定义算术,你可以做struct meta\u data*returnPointer;returnPointer=meta;returnPointer++;returnPointer;
应该避免returnPointer+=…
,因为C没有在void*
上定义算术,你可以这样做struct meta_data*returnPointer;returnPointer=meta;returnPointer++;returnPointer;
。