[英](C) How to write to/read from memory address returned by mmap?
我已經閱讀了一些關於如何提問的頁面,所以我希望這符合標准。
我們的教授希望我們建立一個自定義的malloc和free,一個使用伙伴分配。 他沒有亂用堆,而是希望我們只使用mmap從操作系統請求1 GiB的空間:
MAX_MEM = 1 << 30.
void * base = mmap(NULL, MAX_MEM, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
每個內存塊應該有一個標頭,如果內存為空,則通過鏈表指向下一個和前一個空閑塊。
我不知道怎么說“我想把這些具體數據放在這個特定的地方。” 我想象一個免費的塊在內存中看起來像這樣:
[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
存儲到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;
抱歉,這可能無法編譯,但關於轉換指針的基本想法是可靠的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.