使用' realloc()'在运行时发生崩溃,为什么? - C语言

时间:2018-01-01 03:03:10

标签: c

我有一个数组,我想在运行时增加它的大小。我通过使用循环为数组的元素赋值,当循环的索引达到数组的元素数时,我想增加数组的大小。

我做了什么,实际上是有效的;我可以为数组的元素赋值,我通常无法在不增加数组大小的情况下为其分配任何值。不好的一面是,它在程序运行并顺利完成后让我崩溃。这有什么不对?可能是我尝试为阵列分配的内存已经填满了吗?

int main()
{
    int arr[3];
    int num_of_elements = sizeof(arr)/sizeof(arr[0]); // This gives '3', I checked

    for(i = 0; i < 10; i++)
    {  
        if(i == num_of_elements)
        {
            num_of_elements = num_of_elements + 10;
            realloc(arr, num_of_elements);
        }
        arr[i] = i+10;
        printf("%d\n", arr[i]);
    }

    return 0;
}

2 个答案:

答案 0 :(得分:5)

你正在调用未定义的行为。来自standard §7.22.3.5

void *realloc(void *ptr, size_t size);
  

如果ptr是空指针,则realloc函数的行为类似于malloc   指定大小的函数。 否则,如果ptr与a不匹配   指针先前由内存管理函数返回,或者如果是   通过调用free或realloc函数释放空间,   行为未定义。如果新对象的内存不可用   已分配,旧对象未释放,其值为   不变。

通过内存管理功能 - 它意味着malloc等。arr不是动态分配的内存。因此将此传递给realloc是未定义的行为 - 在您的情况下,行为会导致您在程序中崩溃。

如果你这样做会有用

int *arr = malloc(sizeof(int)*3);
if( arr == NULL){
  perror("Malloc failed");
  exit(EXIT_FAILURE);
}

...
int *p = realloc(arr,num_of_elements*sizeof(int));
                       ^^^^^
if(p == NULL ){
   perror("realloc failed");
   exit(EXIT_FAILURE);
}
arr = p;

检查realloc的使用方式。

外卖将是: -

  • 检查reallocmalloc的返回值。
  • 你试图重新分配额外的10个元素,你需要10*sizeof(int)个内存。
  • 不要 arr = realloc(arr,SIZE)如果realloc失败,您的内存会泄漏。

为什么realloc parr=p之后才会realloc

目前有两个原因

  • 答案是当NULL失败时,如果您将arr分配给NULL,它现在会返回realloc,那么您可能会遇到失去的情况对先前分配的内存的唯一引用 - 导致内存泄漏。这就是为什么我们这样做的原因。

  • 请注意标准

  

may函数返回指向新对象的指针( 可能   与指向旧对象的指针具有相同的值),或一个空指针   如果无法分配新对象

请注意arr部分 - 它可能与DataTemplate指向的地址相同,或者可能不同。这解释了为什么我们应该将它存储在一些临时指针中,然后我们稍后再分配它。

答案 1 :(得分:1)

你应该这样做:

arr = realloc(arr, num_of_elements);
^^^^^

realloc()不一定扩展或缩小已分配的内存就地,它使第一个参数指向的动态内存无效并分配新内存,同时保留内存以前的记忆。

一种可能的实现方式是:

void* realloc(void* ptr, size_t size) {
    void* ret = malloc(size);
    if (ret == NULL) return ret;
    if (ptr != NULL) {
        memcpy(ret, ptr, /* previous size from system */);
        free(ptr);
    }
    return ret;
}