gpt4 book ai didi

c - (C) 如何写入/读取 mmap 返回的内存地址?

转载 作者:太空狗 更新时间:2023-10-29 15:41:44 24 4
gpt4 key购买 nike

我已经阅读了一些关于如何提问的页面,所以我希望这是符合标准的。

我们的教授希望我们构建一个自定义的 malloc 和免费的,一个使用伙伴分配的。他希望我们只使用 mmap 从操作系统请求 1 GiB 的空间,而不是弄乱堆:

MAX_MEM = 1 << 30.
void * base = mmap(NULL, MAX_MEM, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);

每个内存块都应该有一个头,如果内存为空,则通过链表指向下一个和上一个空闲 block 。

我不知道怎么说“我想把这个特定的数据放在这个特定的地方”。我会想象一个空闲 block 在内存中看起来像这样:

[Occupancy (1 bit)][Size (7 bits)][prev pointer (8 bytes)][next pointer (8bytes)][junk]

假设整个 1 GiB 都是免费的。伪代码:

Occupancy = 0; // 0 if empty, 1 if allocated
Size = 0011110; // where size in bytes = 2^Size
next = NULL;
prev = NULL; //note that these are part of a struct called mallocList

如何在我想要的地址创建这些变量?

我试过了,

int MAX_MEM = 1 << 30;
base = mmap(NULL, MAX_MEM, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);

*((unsigned char*) base) = 0x1E;
struct mallocList* temp;
temp->prev = NULL;
temp->next = NULL;
void* tempaddr = base + 1;

*((struct mallocList*) tempaddr) = *temp;

munmap(base, 1 <<30);

编译和运行没有问题,但我意识到试图访问这些值,

printf("%c", *base); //line 37
struct mallocList* two;
two->prev = NULL;
two->next = NULL;
tempaddr->next = *two; //line 41

编译器说,

3.c:37: warning: dereferencing ‘void *’ pointer
3.c:37: error: invalid use of void expression
3.c:41: warning: dereferencing ‘void *’ pointer
3.c:41: error: request for member ‘next’ in something not a structure or union

所以我认为我存储或检索数据的方法有问题,如果能提供任何帮助,我将不胜感激。

这是一个头文件 mymalloc.h:

void *my_buddy_malloc(int size);
void my_free(void *ptr);

struct mallocList
{
struct mallocList *prev;
struct mallocList *next;

} mallocList;

最佳答案

您的编译器错误解释了主要问题:您不能取消引用 void* .将指针指向 char*并存储您想要的任何字节,或将其转换为 struct yourstruct *并使用 p->field 存储到结构字段.

/* You need to tell gcc to pack the struct without padding,
* because you want the pointers stored starting with the second byte, i.e. unaligned.
* That's actually fine in *this* case, since they won't cross a cache-line boundary.
* They'll be at the beginning of a page, from mmap, and thus the beginning of a cache line.
* Modern CPUs are fast at handling misaligned loads within a cache line.
*/

struct __attribute__ ((__packed__)) mem_block {
unsigned int occupied:1;
unsigned int size:7; // bitfields. Not necessarily a good idea. Just using a signed int yourself might be better. positive for allocated, negative for free.
struct mallocList { // nested definition. You can do this differently
struct mallocList *prev, *next;
} pointers;
}; // don't need the type-name here. That would declare a variable of the struct type.


int MAX_MEM = 1 << 30;
void *base = mmap(NULL, MAX_MEM, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);

char *cp = base;
cp[0] = size << 1 | 1; // pack the size and occupied bits into a byte
struct mallocList *mlp = (struct mallocList*)(cp+1); // This avoids needing a compiler-specific way to pack your struct.

// or
struct mem_block *mbp = base;
mbp->occupied = 1;
mbp->size=whatever;
mbp->pointers.prev = NULL;
mbp->pointers.next = NULL;

抱歉,这可能无法编译,但是关于转换指针的基本思想是可靠的。

关于c - (C) 如何写入/读取 mmap 返回的内存地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33716416/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com