1

阅读一些文献,我能够理解它realloc接受一个 void 指针和一个大小变量,并重新分配 void 指针指向的块的内存。

  • 如果在一个字符大小的realloc整数指针 ( ) 上调用会发生什么?int *反之亦然。

  • 这有什么可能的应用?(一个例子肯定会有所帮助。)

4

5 回答 5

7

realloc()功能是多合一的内存管理系统。

  • 如果使用空指针和非零大小调用,它会分配内存。
  • 如果使用有效指针和零大小调用,它会释放内存。
  • 如果使用有效指针和非零大小调用,它会更改分配内存的大小。

如果你调用realloc()一个无效的指针——一个不是从 获得的malloc()calloc()或者realloc()——那么你会得到未定义的行为。

您可以将realloc()整数指针传递给分配的sizeof(char)字节空间(1 个字节),但您将面临调用未定义行为的危险。问题不在于realloc();它与被赋予不可用整数指针的代码有关。由于只分配了 1 个字节但sizeof(int)大于 1(基本上在所有系统上;可能会有例外,但对于提出这个问题的人来说除外),没有安全的方法来使用该指针,除非将它传递给free()or realloc()

鉴于:

int *pointer = malloc(sizeof(char));

您不能这样做*pointer = 0;,因为没有(正式)分配足够的空间供它写入。您不能这样做int x = *pointer;,因为没有(正式)分配足够的空间供它读取。“正式”这个词是因为在实践中,内存分配器分配一个最小大小的块,通常是 8 或 16 个字节,所以实际上在一个字节之后还有空间。但是,您正在超出标准保证的范围,并且可以设想内存分配器将恰好给您一个字节。所以,不要冒险。指向分配内存的单个字节的整数指针是不可用的,除非作为内存分配函数的参数。

的第一个参数realloc()是 a void *。由于您将在范围 ( #include <stdlib.h>) 中拥有一个原型,因此编译器会将 转换int *为 a void *(如果对这种转换有任何事情要做的话),并且只要分配了指向的空间,一切都会好起来的;realloc()将更改分配大小,可能返回相同的指针或可能返回不同的指针,或者如果新大小为零字节,它将释放空间。

于 2013-01-05T16:33:05.650 回答
2

NULL传递给 的非指针有一个非常重要的要求realloc:它们本身必须来自对 或 的调用,malloc否则行为是未定义的。callocrealloc

如果您分配一块足够存储 an 的内存int,然后realloc为 a char,您将始终返回相同的指针,因为sizeof(char)小于或等于sizeof(int)

int* intPtr = malloc(sizeof(int));
int* otherPtr = realloc(intPtr, sizeof(char));
// intPtr == otherPtr

如果你反过来尝试,你几乎肯定也会得到相同的指针,因为内存分配器很少,如果有的话,将内存分配到小于sizeof(int). 然而,结果是依赖于实现的,所以理论上你可能会得到一个不同的地址。

就上述任何练习的实用性而言,它没有用处:realloc旨在帮助您管理可变大小的数组,简化增加此类数组大小的代码,并可能减少分配和复制。我看不出realloc使用标量的理由。

于 2013-01-05T16:29:28.210 回答
0

的第一个参数的类型reallocvoid *,正如你自己所说。因此,您传递的函数参数将转换为 void 指针,这是一种隐式且安全的转换。

本质上,这就像您使用带有long int参数的参数调用函数一样。int

于 2013-01-05T16:24:42.040 回答
0

Realloc 以字节为单位获取大小。如果你这样做

int* a= malloc(sizeof(int));

进而

a=realloc(a,1);

当然 a 现在对于 int 类型来说还不够大,并且在其中写入 int 会给您带来奇怪的行为。

于 2013-01-05T16:25:20.937 回答
0

正如 dasblinkenlight 所述,realloc 对于标量没有意义。在您的示例中:

int * a = malloc(sizeof(int));
int * b = realloc(a,sizeof(char));

将导致a == b,仅仅是因为sizeof(char) < sizeof(int)并且没有理由将数据移动到新位置。
不同之处在于,在 realloc 之后,您将 int 写入未分配的空间,因为您使用 realloc 减少了分配的空间。在这里,这仅具有理论意义。由于对齐,操作系统不太可能重用已释放的内存。但你不应该依赖它。这是未定义的行为。
如果您将 long int 的空间调整为 int,它可能会变得相关。这取决于您的架构。
写入未分配的空间就像放置一个定时炸弹,不知道它什么时候会爆炸。您应该只读取/写入分配的空间。

于 2013-01-05T17:04:08.653 回答