C语言 我的 realloc 函数返回分段错误



我写了函数 - malloc, free 和 realloc malloc 函数工作正常。问题在于 realloc 的功能,它返回我分段错误,我不知道为什么会发生这种情况。如果您帮助我了解为什么会发生这种情况以及我如何解决它,我将很高兴。

我的代码 -

#include <unistd.h>
#include <stdio.h>
void *malloc (size_t size);
void *realloc (void *ptr, size_t size);
void free (void *ptr);
typedef struct metadata_block *p_block;
struct metadata_block
{
  size_t size;
  p_block next;
  int free;
};
p_block head = NULL;
int
main ()
{
  char *str;
  int *a;
  a = (int *) malloc (4);
  scanf ("%d", a);
  printf ("String = %dn", *a);
  a = (int *) realloc (str, 25);
  scanf ("%d", a);
  printf ("String = %dn", *a);
  return 0;
}
void *
malloc (size_t size)
{
  void *my_malloc;
  p_block tmp;
  if (size <= 0)
    {
      return NULL;
    }
  if (head == NULL)
    {
      head = (void *) sbrk (size + sizeof (struct metadata_block));
      head->size = size;
      head->free = 0;
      head->next = NULL;
      return (void *) head + sizeof (struct metadata_block);
    }
  else
    {
      p_block tmp = head;
      while (tmp->next != NULL)
        {
          tmp = tmp->next;
        }
      tmp->next = (void *) sbrk (size + sizeof (struct metadata_block));
      tmp->size = size;
      tmp->free = 1;
      tmp->next = NULL;
      return (void *) size + sizeof (struct metadata_block);
    }
}
void *
realloc (void *ptr, size_t size)
{
  void *newptr;
  if (ptr == NULL)
    {
      return malloc (size);
    }
  if (size == 0)
    {
      return (ptr);
    }
  newptr = malloc (size);
  return (newptr);
}
void
free (void *ptr)
{
  p_block tmp;
  if (tmp->free == 1)
    {
      tmp = 0;
    }
  ptr = NULL;
}

你的 realloc 应该像这样运行:

  • 如果ptr == NULL,那么就malloc
  • 如果ptr != NULL
    • malloc新大小的新指针 ( newPtr
    • ptrnewPtr memcpy内容
    • 免费ptr
    • 返回newPtr

请记住,realloc需要一个指针,该指针是从调用到malloc(或 NULL)时给出的。

恕我直言,实现 realloc 的行为,如果可能的话,它会尝试返回相同的地址,这对于您的任务来说太复杂了。

OP的realloc(),我们称之为realloc_gold()(和malloc_gold() free_gold()),需要复制数据内容和其他修复。

void *realloc_gold(void *ptr, size_t size) {
  if (ptr == NULL) {
    return malloc_gold(size);
  }

当大小为 0 时,释放当前ptr,最好以与malloc_gold(0)相同的方式处理

  if (size == 0) {
    free_gold(ptr);
    return malloc_gold(ptr);
  }

检测 OOM 并复制数据内容。 当然这就引出了问题,oldsize是什么? C 标准malloc()realloc()以某种方式保存该信息,但用户代码通常无法访问该信息。 所以这段代码需要保存它。 通常的解决方案是分配请求的大小 + size_t的大小,并将大小信息放在返回的指针之前。 假设malloc_gold()这样做。

  void *newptr = malloc_gold(size);
  if (newptr != NULL) {
    true
    size_t oldsize = ((struct metadata_block *) ptr)[-1].size;
    memcpy(newptr, ptr, size < oldsize : size : oldsize);
    free_gold(ptr);
  }
  return (newptr);
}

malloc_gold()free_gold()需要考虑领先的大小 - 所以还有一些工作留给 OP。

The following is close to what you want, however, read all the commentary.
//#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void *myMalloc  (size_t size);
void *myRealloc (void *ptr, size_t size);
void  myFree    (void *ptr);
//typedef struct metadata_block *p_block;
struct metadata_block
{
    size_t size;
    //p_block next;
    struct metadata_block * next;
    int free;
};
//p_block head = NULL;
struct metadata_block *head = NULL;
int main ()
{
    //char *str;
    char * str = NULL;
    int *a;
    //a = (int *) malloc (4);
    // following is not correct because myMalloc
    // returns parameter*sizeof(struct meta_block)
    // probably should call system malloc() instead of myMalloc()
    if( NULL == (a = myMalloc( sizeof(int) ) ) ) 
    { // myMalloc failed
        perror("myMalloc failed");
        exit( EXIT_FAILURE );
    }
    // implied else, myMalloc successful
    //scanf ("%d", a);
    if( 1 != scanf(" %d", a) ) 
    { // scanf failed
        perror("scanf 1 failed" );
        myFree( a );
        exit( EXIT_FAILURE );
    }
    // implied else, scanf successful
    printf ("String = %dn", *a);
    //a = (int *) realloc (str, 25);
    int * b;
    if( NULL == (b = myRealloc( str, 25 ) ) )
    { // then, myRealloc failed
        perror( "myRealloc failed" );
        myFree(a);
        exit( EXIT_FAILURE );
    }
    // implied else, myRealloc successful
    a = b;
    //scanf ("%d", a);
    if( 1 != scanf(" %d", a ) )
    { // then, scanf failed
        perror( "scanf 2 failed" );
        exit( EXIT_FAILURE );
    }
    // implied else, scanf successful
    printf ("String = %dn", *a);
    // <-- added following line so no memory leaks
    myFree( a );
    return 0;
} // end function: main

void *myMalloc (size_t size)
{
    //void *my_malloc;
    //p_block tmp;
    if (size <= 0)
    {
        return NULL;
    }
    if (head == NULL)
    {
        if( NULL == (head = malloc(sizeof(struct metadata_block)*(size))) )
        { // then, malloc failed
            perror( "malloc failed" );
            exit( EXIT_FAILURE);
        }
        // implied else, malloc successful
        head->size = size;
        head->free = 0;
        head->next = NULL;
        return (void *) head + sizeof (struct metadata_block);
    }
    else
    {
        struct metadata_block* tmp = head;
        // step through existing linked list
        while (tmp->next != NULL)
        {
            tmp = tmp->next;
        }
        // initialize new metadata_block instance
        //tmp->next = (void *) sbrk (size + sizeof (struct metadata_block));
        tmp->next = malloc(sizeof(struct metadata_block)*(size+1));
        tmp->size = size;
        tmp->free = 1;
        tmp->next = NULL;
        return (void *) size + sizeof (struct metadata_block);
    }
} // end function: myMalloc

void *realloc (void *ptr, size_t size)
{
    void *newptr;
    if (ptr == NULL)
    {
        return malloc (size);
    }
    if (size == 0)
    {
        return (ptr);
    }
    newptr = malloc (size);
    return (newptr);
} // end function: realloc

// <-- the function myFree fails to actually free anything
//     and tmp is being used without first being set to something
void myFree (void *ptr)
{
    //p_block tmp;
    struct metadata_block *tmp = ptr;
    if (tmp->free == 1)
    {
        tmp = 0; // <-- this looses the allocated memory pointer
                 //     without actually freeing the allocated memory
    }
    ptr = NULL;  // <-- this has no effect on the rest of the program allocated memory
                 //     because C passes by value, not by reference
} // end function: myFree

相关内容

  • 没有找到相关文章

最新更新