c - 使用此内存分配器时收到分段错误
问题描述
我正在尝试实现一个可以由多个进程一次调用的内存分配器,所以我使用共享内存来保持分配的第一个和最后一个内存块的信息,两者都放在共享内存的前 32 个字节和之后我试图从共享内存中的 getpagesize() 偏移量进行简单分配,以查看它是否有效,但是在使用它分配一个简单的整数变量时,我不断收到分段错误,我不知道为什么。
#include <unistd.h>
#include <string.h>
#include <pthread.h>
/* Only for the debug printf */
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
typedef char ALIGN[16];
union header {
struct {
size_t size;
unsigned is_free;
union header *next;
} s;
/* force the header to be aligned to 16 bytes */
ALIGN stub;
};
typedef union header header_t;
header_t *get_free_block(size_t size)
{
char shm_name[] = "memalloc";
int shm_fd;
shm_fd = shm_open(shm_name, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
if (shm_fd < 0)
{
perror(NULL);
return NULL;
}
size_t shm_size = 10 * getpagesize();
if (ftruncate(shm_fd, shm_size) == -1)
{
perror(NULL);
shm_unlink(shm_name);
return NULL;
}
char* shm_ptr = mmap(0, shm_size, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (shm_ptr == MAP_FAILED)
{
perror(NULL);
shm_unlink(shm_name);
return NULL;
}
header_t *head;
if (shm_ptr)
head = (header_t*)shm_ptr;
else
head = NULL;
header_t *tail;
if (head)
tail = (header_t*)(shm_ptr + 16);
else
tail = NULL;
header_t *curr = head;
while(curr) {
/* see if there's a free block that can accomodate requested size */
if (curr->s.is_free && curr->s.size >= size)
return curr;
curr = curr->s.next;
}
return NULL;
}
void *malloc(size_t size)
{
char shm_name[] = "memalloc";
int shm_fd;
shm_fd = shm_open(shm_name, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
if (shm_fd < 0)
{
perror(NULL);
return NULL;
}
size_t shm_size = 10 * getpagesize();
if (ftruncate(shm_fd, shm_size) == -1)
{
perror(NULL);
shm_unlink(shm_name);
return NULL;
}
char* shm_ptr = mmap(0, 32, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (shm_ptr == MAP_FAILED)
{
perror(NULL);
shm_unlink(shm_name);
return NULL;
}
header_t *head;
if (shm_ptr)
head = (header_t*)shm_ptr;
else
head = NULL;
header_t *tail;
if (head)
tail = (header_t*)(shm_ptr + 16);
else
tail = NULL;
size_t total_size;
void *block;
header_t *header;
if (!size)
return NULL;
header = get_free_block(size);
if (header) {
/* Woah, found a free block to accomodate requested memory. */
header->s.is_free = 0;
return (void*)(header + 1);
}
/* We need to get memory to fit in the requested block and header from OS. */
total_size = sizeof(header_t) + size;
int nr_pagesize = 1;
block = mmap(0, total_size, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, nr_pagesize * getpagesize());
if (block == MAP_FAILED)
{
perror(NULL);
shm_unlink(shm_name);
return NULL;
}
header = block;
header->s.size = size;
header->s.is_free = 0;
header->s.next = NULL;
if (!head)
head = header;
if (tail)
tail->s.next = header;
tail = header;
return (void*)(header + 1);
}
这是测试程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int *x = (int*)malloc(sizeof(int));
return 0;
}
我在终端上使用的命令是:
gcc -o memalloc.so -fPIC -shared memalloc.c
export LD_PRELOAD=$PWD/memalloc.so
gcc helloworld.c -o hello
编译测试程序后,我得到了分段错误。
解决方案
推荐阅读
- sql - 如何选择/调用 sakila 数据库中存储的函数
- angular - 为什么角度自定义验证器在初始页面加载时被调用两次以及如何防止它?
- c# - C# 从结果视图中获取价值
- docker - 环境属性未注入到卷映射
- css - Boostrap css将图像作为叠加层放在标题中
- exception - 从受管软件包的目标组织获取详细顶点错误/异常的最佳方法
- angular - 角度材料 mat-align-tabs 属性未正确对齐
- android - 从 API 获取并显示在屏幕上的图像/图片在截屏和通过社交媒体分享时不会被捕获
- php - 使用 python 的请求库从 PHP 页面获取 JSON 对象
- sqlite - 将表 X 中 3 列的日期添加到表 Y 中的一列