【问题标题】:How to properly use realloc in c? [duplicate]如何在c中正确使用realloc? [复制]
【发布时间】:2018-11-24 16:49:37
【问题描述】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define LENGHT 20

typedef struct {
    unsigned id;
    char name[LENGHT];
    char genre[LENGHT];
    char nazionality [LENGHT];
    int year_carrier_started;
    bool check;
}Artist;

void print(Artist *arr, int *i);
void addOne(Artist *arr, int *i);

int main(void) {

    int index = 5;
    Artist *array = malloc(sizeof(int)*index);
    for (int i=0;i<index;i++)
    {
        printf("Insert a number:\n");
        scanf("%d",&array[i].id);
    }
    do
    {
        addOne(array,&index);
        print(array,&index);
    }while(1);

    system("pause");
    free(array);
    return EXIT_SUCCESS;
}


void addOne(Artist *arr, int *i)
{
    realloc(arr,sizeof(Artist)*(*i)+1);
    printf("Insert another one:\n");
    scanf("%d",&arr[*i].id);
    *i = *i +1;
    print(arr,i);
}


void print(Artist *arr, int *i)
{
    for (int j=0;j<*i;j++)
    {
        printf("Number: %d position %d\n",arr[j].id,j);
    }
}

大家好,我从我的一段程序中得到了这个结构,我需要做的是每次用户想要添加一个新的艺术家时重新分配。在添加了大约 10/15 的用户后,它会无缘无故地崩溃(至少对我来说没有)。我究竟做错了什么? (Dat *i 是通过引用传递的,它计算已经有多少艺术家)。

【问题讨论】:

  • 提示:为什么要在 sizeof(Artist)*(*i)+1 中 +1?
  • realloc 可能会将您的数据移动到另一个位置,因此您不能相信arr 仍然有效。这就是 realloc 还返回分配的内存位置的原因。
  • @chux 是的,我很抱歉,因为我修改了每个语句的 *i 所以,我这样做加上 1
  • 有没有办法将我的代码与功能一起发布?不幸的是,它没有被识别为代码,所以我需要 Ctrl + k 它的每一行......
  • 我编辑了一个 MCVE

标签: c


【解决方案1】:

如何在c(?)中正确使用realloc

在添加了大约 10/15 个用户后,它会因为 no 原因而崩溃

@Christian Gibbons 好建议:使用realloc() 的返回值。 array 以前的值可能无效。


乘以正确的值

// sizeof(Artist)*(*i)+1
sizeof(Artist)*((*i)+1)

使用realloc()的返回值

// realloc(array,sizeof(Artist)*(*i)+1);
void *new_ptr = realloc(array,....

检查 realloc() 结果

// realloc(array,sizeof(Artist)*(*i)+1);
void *new_ptr = realloc(array,....
if (new_ptr == NULL) OutOfMemory();
else array = new_ptr;

考虑对象的大小而不是类型

// realloc(array,sizeof(Artist)*(*i)+1);
void *new_ptr = realloc(array, sizeof *array *((*i)+1)); 

大家一起

Artist *array = malloc(sizeof *array);
if (array == NULL) Handle_OutOfMemory();
...
void *new_ptr = realloc(array, sizeof *array * ((*i)+ 1));
if (new_ptr == NULL) {
  // `array` still has *i elements assigned to it.
  Handle_OutOfMemory();
} else {
  array = new_ptr;
  (*i)++;
}

【讨论】:

  • 我编辑了我发布代码的帖子,你能帮我吗?
  • @GeneNight 我相信人们可以使用此答案并将其应用于您更新的帖子。
  • @GeneNight addOne(array,&amp;index); .... void addOne(Artist *arr, int *i) 也需要传递调用arr 的地址。 --> addOne(&amp;array,&amp;index); ... void addOne(Artist **arr, int *i)
  • “Handle_OutOfMemory()”是什么意思?
  • @GeneNight 关于is still crashes,您是否按照here 的建议对addOne() 进行了修复?
【解决方案2】:

realloc 将尝试在可能的情况下调整分配的内存大小,但如果没有足够的空间扩展到新的大小,则必须将数据移动到新位置。由于这个原因,Realloc 返回一个指向该位置的指针。您还应该进行测试以确保它没有出错。所以是这样的:

Artist *arr = malloc(sizeof(*arr) * i);
Artist *temp = realloc(arr, sizeof(Artist)*((*i)+1) // Borrowing this from Yunnosch
if(temp) {
    arr = temp;
}
else {
    free(arr);
    // more error handling
}

【讨论】:

  • 在添加 100 多条记录后仍然崩溃怎么办?至少它处理了一些内存泄漏,而且它可以工作 *5 次以上
猜你喜欢
  • 1970-01-01
  • 2017-12-01
  • 2014-01-27
  • 1970-01-01
  • 2014-02-08
  • 2021-02-25
  • 2019-05-11
  • 1970-01-01
  • 2016-01-22
相关资源
最近更新 更多