我正在尝试编写内存分配接口。将 new_buf_addr 从 myalloc 函数返回到main并将其分配给变量 temp ,在gdb中检查时,会出现Seg错误。返回值不是指向本地值的指针,所以我想这不是问题。我试图返回其他类型,但结果相同
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
void* HEAD = NULL;
void* NULLPTR = (void*)10;
std::size_t ATTRS_SIZE = 2*sizeof(NULL) + sizeof(std::size_t) + sizeof(char);
// BUFFER STRUCT
// |--prev--|--next--|--size--|--flag--|–––––––––––data–––––––––––|
// |---8b---|---8b---|---8b---|---1b---|
// |---------------25b-----------------|––––––––size - 25b––––––––|
// flag:
// 0 - busy
// 1 - free
// add metadata
void init_buf(void *buf, std::size_t size, void *prev, void *next, char free_flag ){
printf("%d\n", sizeof(prev) );
memcpy(buf, prev, sizeof(prev));
memcpy(buf + sizeof(NULL), next, sizeof(next));
memcpy(buf + 2*sizeof(NULL), &size, sizeof(std::size_t));
memcpy(buf + 2*sizeof(NULL) + sizeof(std::size_t), &free_flag, sizeof(char));
}
// setups buffer where memory will be allocated
void mysetup(void *buf, std::size_t size)
{
HEAD = buf;
init_buf(buf, size, &NULLPTR, &NULLPTR, 1);
}
void* myalloc(std::size_t size)
{
void* buf = HEAD;
while (true) {
// getting buf attrs
void* prev;
void* next;
std::size_t* buf_size;
char free_flag;
printf("%d %d %d\n", sizeof(buf), sizeof(void*), sizeof(prev));
// memcpy(prev, buf, sizeof(void*));
prev = buf;
// memcpy(next, buf + sizeof(NULL), sizeof(void*));
next = buf + sizeof(NULL);
memcpy(buf_size, buf + 2*sizeof(NULL) , sizeof(std::size_t));
memcpy(&free_flag, buf + 2*sizeof(NULL) + sizeof(std::size_t), sizeof(char));
// check if buf is free and big enough to allocate
if (size < *buf_size && free_flag){
void* new_buf_addr = buf + *buf_size - ATTRS_SIZE - size;
// point buf's next to new buf
memcpy(next, new_buf_addr, sizeof(new_buf_addr));
init_buf(new_buf_addr, size, buf, &NULLPTR, 0);
new_buf_addr = new_buf_addr + ATTRS_SIZE;
return new_buf_addr;
}
// going to next buf
else {
if (next == &NULLPTR) {
printf("%s\n", "Can't allocate memory");
return NULL;
}
else {
buf = next;
}
}
}
}
void myfree(void *p)
{
while (true){
void *left_neighbor;
memcpy(left_neighbor, p - ATTRS_SIZE, sizeof(void*));
void *right_neighbor;
memcpy(right_neighbor, p - ATTRS_SIZE + sizeof(void*), sizeof(void*));
std::size_t* size;
memcpy(size, p - ATTRS_SIZE + 2 * sizeof(void*) , sizeof(std::size_t));
char* free_flag;
memcpy(free_flag, p - sizeof(char), sizeof(char));
bool is_right = false;
if (right_neighbor != &NULLPTR) {
bool right_is_free = *((char*)(right_neighbor + ATTRS_SIZE - sizeof(char))) == 1;
if (right_is_free) {
is_right = true;
}
}
bool is_left = false;
if (left_neighbor != &NULLPTR) {
bool left_is_free = *((char*)(right_neighbor + ATTRS_SIZE - sizeof(char))) == 1;
if (left_is_free) {
is_left = true;
}
}
if (is_right) {
memcpy(size, p - ATTRS_SIZE + 2 * sizeof(void*) , sizeof(std::size_t));
void* right_next;
std::size_t* right_size;
memcpy(right_next, right_neighbor + sizeof(void*), sizeof(void*));
memcpy(right_size, right_neighbor + 2 * sizeof(void*), sizeof(std::size_t));
// set p->next to right_neighbor's next
memcpy(right_neighbor, right_next, sizeof(void*));
// adding right_neighbor->size to p->size
*size = *size + *right_size;
}
else if (is_left){
memcpy(left_neighbor + sizeof(void*), right_neighbor, sizeof(void*));
std::size_t* new_size;
// set left_neighbor->next to p->next
memcpy(new_size, left_neighbor + 2 * sizeof(void*), sizeof(std::size_t));
//adding p->size to left_neighbor->size
*new_size = *new_size + *size;
// pointig p to data to keep cycle alive
p = left_neighbor + ATTRS_SIZE;
}
else {
// Just in case if is 0 set it to 1
char flag = 1;
memcpy(p - sizeof(char), &flag, sizeof(char));
return;
}
}
}
int main() {
void* ret[10];
std::size_t buf_size = 100*1024;
void* buf = malloc(buf_size);
mysetup(buf, buf_size);
std::size_t block_size = 16;
int i = 0;
while(1) {
void* temp = myalloc(block_size);
ret[i] = temp;
if(ret[i] == NULL) break;
i++;
}
for(int j = 0; j < i; j++) {
std::size_t rnd = (rand()/(double)RAND_MAX*(i-1));
void* swp = ret[rnd];
ret[rnd] = ret[j];
ret[j] = swp;
}
for(int j = 0; j < i; j++) {
myfree(ret[j]);
}
return 0;
}
答案 0 :(得分:0)
好的,看看稀疏的评论,“8b”表示“8字节”,看起来像是你计划从sizeof(NULL)
获得的指针大小。而std::size_t
意味着你正在编译C ++。
在C ++中,NULL
不是指针。 sizeof(NULL)
可以小于或大于sizeof(void*)
。我希望您的系统#define NULL 0
和sizeof(NULL)==4
。不是8个字节。
答案 1 :(得分:0)
问题在于void* prev
和void* next
应为void**
,因为 prev 和 next 是指向另一个缓冲区,也是指针