【问题标题】:custom memory allocator - segfault自定义内存分配器 - 段错误
【发布时间】:2018-06-28 15:42:55
【问题描述】:

我和我的朋友正在尝试在 linux ubuntu 16.04 中开发自定义内存分配器。 我们因为错误而卡住了,顺便说一句,这是我们第一次 我们正在尝试编写类似的代码,因此我们不是最好的调试器,错误是:分段错误(核心转储) 这是代码。 任何人都可以帮助我们了解什么是错的? 谢谢!

#include <unistd.h>
#include <string.h>
#include <pthread.h> 
#include <stdio.h>

struct header_t {   
size_t size;
unsigned is_free;
struct header_t *next; };

struct header_t *head = NULL, *tail = NULL; 
pthread_mutex_t global_malloc_lock;

struct header_t *get_free_block(size_t size)
 {  
struct header_t *curr = head;   
while(curr) {   
/* see if there's a free block that can accomodate requested size */        
if (curr->is_free && curr->size >= size)
        return curr;
    curr = curr->next; 
}   
return NULL; 
}

void free(void *block) 
{   
struct header_t *header, *tmp;
/* program break is the end of the 
process's data segment */   
void *programbreak;

if (!block)         
return;
pthread_mutex_lock(&global_malloc_lock);
header = (struct header_t*)block - 1;

/* sbrk(0) gives the current program break address */


programbreak = sbrk(0);

/*
   Check if the block to be freed is the last one in the
   linked list. If it is, then we could shrink the size of the
   heap and release memory to OS. Else, we will keep the block
   but mark it as free.      */ 

if ((char*)block + header->size == programbreak) { 
    if (head == tail) { 
        head = tail = NULL;
       } else { 
        tmp = head;             
           while (tmp) {
            if(tmp->next == tail) {
                tmp->next = NULL;
                tail = tmp;
            }
            tmp = tmp->next;
        }
    }       
/* sbrk() with a negative argument decrements the program break.
       So memory is released by the program to OS.      */


    sbrk(0 - header->size - sizeof(struct header_t)); 


    /* Note: This lock does not really assure thread
       safety, because sbrk() itself is not really
       thread safe. Suppose there occurs a foregin sbrk(N)
       after we find the program break and before we decrement
       it, then we end up realeasing the memory obtained by
       the foreign sbrk().      */      

pthread_mutex_unlock(&global_malloc_lock);
    return;
}
header->is_free = 1;
pthread_mutex_unlock(&global_malloc_lock);
}

void *malloc(size_t size)
{
    size_t total_size;
    void *block;
    struct header_t *header;
    if (!size)
        return NULL;
    pthread_mutex_lock(&global_malloc_lock);
    header = get_free_block(size);
    if (header) {
        /* Woah, found a free block to accomodate requested memory. */
        header->is_free = 0;
        pthread_mutex_unlock(&global_malloc_lock);
        return (void*)(header + 1); 
    } 
    /* We need to get memory to fit in the requested block and header 
from OS. */
    total_size = sizeof(struct header_t) + size;
    block = sbrk(total_size);
    if (block == (void*) -1) {
    pthread_mutex_unlock(&global_malloc_lock);
    return NULL;
}
header = block;
header->size = size;
header->is_free = 0;
header->next = NULL;
if (!head)
    head = header;
if (tail)
    tail->next = header;
tail = header;
pthread_mutex_unlock(&global_malloc_lock);
return (void*)(header + 1);
}

void *calloc(size_t num, size_t nsize)
{
size_t size;
void *block;
if (!num || !nsize)
    return NULL;
size = num * nsize;
/* check mul overflow */
if (nsize != size / num)
    return NULL;
block = malloc(size);
if (!block)
    return NULL;
memset(block, 0, size);
return block;
}


void *realloc(void *block, size_t size)
 {
struct header_t *header;
void *ret;
if (!block || !size)
    return malloc(size);
header = (struct header_t*)block - 1;
if (header->size >= size)
    return block;
ret = malloc(size);
if (ret) {
    /* Relocate contents to the new bigger block */
    memcpy(ret, block, header->size);
    /* Free the old memory block */
    free(block);
  }
  return ret;
 }

【问题讨论】:

  • 提供main()函数来了解你的调用方式。
  • 你有单元测试吗?单元测试是现代软件开发的关键部分,它可以为任何代码提供一种简单的方法来验证其是否正常工作。
  • 我通过在代码前添加函数原型解决了这个错误。

标签: linux pointers debugging memory memory-management


【解决方案1】:

mutex 变量应该在使用它来应用锁之前初始化。你的global_malloc_lock 没有初始化。

你不能从normal variable开始初始化mutex变量。

pthread_mutex_t global_malloc_lock = 0 ;// invalid .. you may thinking since it's it declared as global it's initialized with 0 which is wrong

通过调用pthread_mutex_init()或使用PTHREAD_MUTEX_INITIALIZER ;初始化互斥变量

为您的代码添加此

pthread_mutex_t global_malloc_lock = pthread_mutex_t global_malloc_lock;

【讨论】:

    【解决方案2】:

    出现问题是因为函数没有原型 [decalred]。 一旦我添加了函数原型。代码有效。

    有关原型设计的更多信息:http://www.trytoprogram.com/c-programming/function-prototype-in-c/

    【讨论】:

      猜你喜欢
      • 2012-02-22
      • 2012-07-08
      • 2012-05-29
      • 1970-01-01
      • 1970-01-01
      • 2016-09-29
      • 1970-01-01
      • 2020-08-22
      • 2019-08-11
      相关资源
      最近更新 更多