为什么在 realloc 函数中使用它之前 NULL ing 指针?

Why NULL ing pointer before using it in realloc function?

如果我用 malloc

执行以下操作
HashTableEntry *util = malloc(sizeof(HashTableEntry) * T->capacity);

一切正常。但是,如果我使用 realloc

执行以下操作
HashTableEntry *util = realloc(util, sizeof(HashTableEntry) * T->capacity);

reallocreturnsNULL。我还收到 gcc 的警告,说我在使用它之前没有初始化 util

但是,下面的效果非常好,比如 malloc

HashTableEntry *util = NULL;
util = realloc(util, sizeof(HashTableEntry) * T->capacity);

我的问题是为什么?

我相信正在发生的事情是,在所有情况下,我都在创建一个指针并为其分配我正在分配的堆内存块的起始地址。我哪里错了吗?

从函数调用可以看出

HashTableEntry *util = realloc(util, sizeof(HashTableEntry) * T->capacity);

函数 realloc 使用参数 util。如果它具有不确定的值,则该函数具有未定义的行为。

此外,在使用任何函数之前,您应该阅读其说明和每个参数的用途。

来自C标准(7.22.3.5的realloc函数)

2 The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size....

3 If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size.

一般来说,函数会查看其参数的值并使用这些值来执行某些操作,因此传递特定值而不是随机或未指定的值非常重要。当您编写 HashTableEntry *util = realloc(util, sizeof(HashTableEntry) * T->capacity); 时,您没有告诉编译器在调用 realloc 函数时要在 util 变量中放入什么值,因此您可能会得到未定义的行为,即不好。

  1. 如果第一个参数是空指针,realloc() 对指定大小的行为类似于 malloc()。

  2. 如果第一个 arg 是未初始化的指针(坏指针),realloc() 将无法正常工作,因此它 returns NULL。

  3. 如果第一个参数是有效地址,realloc() 释放旧对象和 returns 指向新对象的指针,或者扩展旧对象的内存(由 OS 决定)。

在第二种情况下,util 在传入 realloc() 时未初始化。 所以 realloc() 的行为是未定义的。

HashTableEntry *util = realloc(util, sizeof(HashTableEntry) * T->capacity);
                             //^^^^ This value is undefined.

在第三种情况下,您将其初始化为 NULL,在这种情况下 realloc() 的行为类似于 malloc()

一些注意事项:

调用realloc()时不要直接赋值给目标指针。而是分配给一个临时指针,然后在分配给目标指针之前检查 (!=NULL)。

那么,if/whenrealloc()失败,原来的指针不会丢失。丢失这样的指针会导致内存泄漏。

注意:realloc()的第一个参数是一个'source'指针。它必须指向有意义的东西,例如 NULL 或堆中的已知位置。