[英](C) How to write to/read from memory address returned by mmap?
I've read some of the pages regarding how to ask questions, so I hope this is up to standard. 我已经阅读了一些关于如何提问的页面,所以我希望这符合标准。
Our professor wants us to build a custom malloc and free, one that uses buddy allocation. 我们的教授希望我们建立一个自定义的malloc和free,一个使用伙伴分配。 Instead of messing with the heap, he wants us to just use mmap to request 1 GiB of space from the OS:
他没有乱用堆,而是希望我们只使用mmap从操作系统请求1 GiB的空间:
MAX_MEM = 1 << 30.
void * base = mmap(NULL, MAX_MEM, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
Each chunk of memory should have a header, and if the memory is empty, pointers to the next and previous free chunks via linked list. 每个内存块应该有一个标头,如果内存为空,则通过链表指向下一个和前一个空闲块。
I don't know how to say "I want to put this specific data in this specific place." 我不知道怎么说“我想把这些具体数据放在这个特定的地方。” I would imagine a free chunk to look like this in the memory:
我想象一个免费的块在内存中看起来像这样:
[Occupancy (1 bit)][Size (7 bits)][prev pointer (8 bytes)][next pointer (8bytes)][junk]
So let's say that the whole 1 GiB is free. 所以,让我们说整个1 GiB是免费的。 Pseudo Code:
伪代码:
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
How would I create these variables at the address I want them in? 我如何在我想要的地址创建这些变量?
I tried this, 我试过这个,
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);
which compiled and ran without issue, but I realized trying to access the values, 编译和运行没有问题,但我意识到尝试访问值,
printf("%c", *base); //line 37
struct mallocList* two;
two->prev = NULL;
two->next = NULL;
tempaddr->next = *two; //line 41
the compiler says, 编译说,
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
So I figure something's either wrong with my method of storing the data or retrieving it, and I'd greatly appreciate any help that could be offered. 因此,我认为存储数据或检索数据的方法有问题,我非常感谢可以提供的任何帮助。
Here's a header file mymalloc.h: 这是一个头文件mymalloc.h:
void *my_buddy_malloc(int size);
void my_free(void *ptr);
struct mallocList
{
struct mallocList *prev;
struct mallocList *next;
} mallocList;
Your compiler error explains the main problem: you can't dereference a void*
. 您的编译器错误解释了主要问题:您无法取消引用
void*
。 Cast the pointer to char*
and store whatever bytes you want, or cast it to a struct yourstruct *
and store to struct fields with p->field
. 将指针转换为
char*
并存储您想要的任何字节,或将其转换为struct yourstruct *
并使用p->field
存储到struct字段。
/* 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;
This might not compile, sorry, but the basic idea about casting pointers is solid. 抱歉,这可能无法编译,但关于转换指针的基本想法是可靠的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.