鱼C论坛

 找回密码
 立即注册
查看: 57|回复: 9

动态内存分配

[复制链接]
发表于 昨天 11:30 From FishC Mobile | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
realloc在分配内存成功后。原内存要不要free释放掉。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 11:30 | 显示全部楼层
realloc 在分配内存成功后,原内存会自动被释放,因此不需要手动调用 free。如果 realloc 失败,返回 NULL,则原内存保持不变,此时应避免释放原内存,以免造成错误。

示例代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int main() {
  4.     int *ptr = malloc(10 * sizeof(int)); // 分配原内存
  5.     if (ptr == NULL) {
  6.         return 1; // 分配失败处理
  7.     }

  8.     int *new_ptr = realloc(ptr, 20 * sizeof(int)); // 重新分配内存
  9.     if (new_ptr == NULL) {
  10.         // realloc 失败,原 ptr 仍有效,需手动管理
  11.         free(ptr); // 释放原内存
  12.         return 1; // 错误处理
  13.     } else {
  14.         // realloc 成功,原内存已自动释放
  15.         ptr = new_ptr; // 更新指针
  16.         // 使用新内存...
  17.         free(ptr); // 最终释放新内存
  18.     }
  19.     return 0;
  20. }
复制代码


关键点:
- realloc 成功时,原内存由系统自动释放,无需额外操作。
- realloc 失败时,原内存仍需手动管理,避免双重释放或内存泄漏。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 11:32 From FishC Mobile | 显示全部楼层
FishC 发表于 2025-12-18 11:30
realloc 在分配内存成功后,原内存会自动被释放,因此不需要手动调用 free。如果 realloc 失败,返回 NULL ...

失败就手动free
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 11:33 | 显示全部楼层
bgc1314159 发表于 2025-12-18 11:32
FishC 发表于 2025-12-18 11:30
realloc 在分配内存 ...


核心答案:
成功:不需要手动 free(realloc 自动处理)
失败:需手动 free 原内存

详细说明:
1. realloc 成功时,系统自动释放原内存块,只需使用新指针:

  1. int *new_ptr = realloc(ptr, new_size);
  2. if (new_ptr) {
  3.     // 原ptr内存已自动释放
  4.     ptr = new_ptr; // 更新指针
  5. }
复制代码


2. realloc 失败时(返回 NULL),原内存块仍有效,需手动管理:

  1. int *new_ptr = realloc(ptr, new_size);
  2. if (!new_ptr) {
  3.     // 扩容失败,原ptr仍然有效
  4.     free(ptr); // 若不再需要则手动释放
  5.     ptr = NULL;
  6. }
复制代码


注意事项:
o 不要对 realloc 成功后的原指针再次 free(会导致双重释放)
o 建议使用临时指针接收 realloc 结果,避免原指针丢失

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 12:10 From FishC Mobile | 显示全部楼层
FishC 发表于 2025-12-18 11:33
核心答案:
成功:不需要手动 free(realloc 自动处理)
失败:需手动 free 原内存

如果用不到原指针应该把它置为NULL。是否正确
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 12:11 | 显示全部楼层
bgc1314159 发表于 2025-12-18 12:10
FishC 发表于 2025-12-18 11:33
核心答案:
成功: ...


正确。

这是防止悬空指针(dangling pointer)的好习惯。释放内存后,原指针仍指向已释放的内存地址,此时若误用该指针,会导致未定义行为。将其置为 NULL 可以避免这一问题。

示例:

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int main() {
  4.     int *ptr = malloc(10 * sizeof(int));
  5.     if (!ptr) return 1;

  6.     // 尝试重新分配内存
  7.     int *new_ptr = realloc(ptr, 20 * sizeof(int));

  8.     if (new_ptr) {
  9.         // realloc 成功:原内存已自动释放,原指针失效
  10.         // 将原指针置为 NULL,防止误用
  11.         ptr = NULL; // 注意:这里 ptr 已赋值为 NULL,不再指向原内存
  12.         // 使用 new_ptr 操作新内存...
  13.         free(new_ptr);
  14.     } else {
  15.         // realloc 失败:手动释放原内存,并将原指针置为 NULL
  16.         free(ptr);
  17.         ptr = NULL;
  18.     }

  19.     return 0;
  20. }
复制代码


关键点:
  • 释放内存(无论是通过 realloc 自动释放还是手动 free)后,应立即将不再使用的指针置为 NULL
  • NULL 操作应在释放之后立即进行,避免出现悬空指针。
  • NULL 指针调用 free 是安全的(标准规定 free(NULL) 无操作)。


注意: 若在 realloc 成功后更新原指针(如 ptr = new_ptr),则原指针已指向新内存,无需额外置 NULL。仅当原指针变量不再指向有效内存时,才需要置 NULL

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 12:12 From FishC Mobile | 显示全部楼层
FishC 发表于 2025-12-18 12:11
正确。

这是防止悬空指针(dangling pointer)的好习惯。释放内存后,原指针仍指向已释放的内存地址 ...

realloc注意事项
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 12:13 | 显示全部楼层
bgc1314159 发表于 2025-12-18 12:12
FishC 发表于 2025-12-18 12:11
正确。

这是防止 ...


realloc 使用注意事项

1. 必须检查返回值
   realloc 可能失败,返回 NULL。如果不检查,直接使用可能导致程序崩溃。

2. 使用临时指针接收返回值
   避免 realloc 失败时原指针丢失,导致内存泄漏。

示例:

int *ptr = malloc(10 * sizeof(int));
// ... 使用 ptr ...

int *temp = realloc(ptr, 20 * sizeof(int));
if (temp) {
    ptr = temp; // 更新指针
    // ... 使用扩容后的内存 ...
} else {
    // 处理失败,原 ptr 仍有效
    // 注意:此时原内存大小不变,如需继续使用,应保持原指针
}

3. 正确处理 realloc 失败
   realloc 失败时,原内存块保持不变。此时应根据需求决定如何处理:是保持原大小继续使用,还是进行错误处理并退出。

4. 避免重复释放
   realloc 成功后,原内存自动释放,切勿再对原指针调用 free。

5. 将无用指针置为 NULL
   释放内存或 realloc 成功后,若原指针不再指向有效内存,应将其置为 NULL,避免悬空指针。

6. 注意 realloc 的特殊情况
   o 当新大小为 0 时,行为相当于 free,并返回 NULL(或一个可free的非NULL指针,具体实现相关)。
   o 当原指针为 NULL 时,行为相当于 malloc。
   o 当新旧大小相同,可能返回原指针(不一定重新分配)。

7. 避免频繁 realloc
   频繁调整内存大小可能影响性能,可考虑预分配或使用更合适的数据结构。

8. 注意多线程环境
   在多线程中使用 realloc 需确保同步,避免多个线程同时操作同一内存块。

9. 内存对齐
   realloc 分配的内存会满足基本对齐要求,但若需要特殊对齐,应使用专用函数(如 posix_memalign)。

10. 跨平台兼容性
    不同系统(如Windows和Linux)的 realloc 实现细节可能有差异,编写可移植代码时应注意。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 12:18 From FishC Mobile | 显示全部楼层
FishC 发表于 2025-12-18 12:13
realloc 使用注意事项

1. 必须检查返回值

失败后原指针应该还在吧,为啥说避免丢失
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 12:19 | 显示全部楼层
bgc1314159 发表于 2025-12-18 12:18
FishC 发表于 2025-12-18 12:13
realloc 使用注意事 ...


使用临时指针是为了避免在 realloc 失败时,原指针被覆盖为 NULL 导致内存泄漏。以下详细说明:

失败时原指针状态:
  • realloc 失败时返回 NULL
  • 原指针指向的内存块仍然存在,内容不变
  • 原指针变量本身的值(即内存地址)保持不变


错误示例(会导致内存泄漏):

int *ptr = malloc(10 * sizeof(int));
// ... 使用ptr...

// 错误:直接用ptr接收realloc结果
ptr = realloc(ptr, 20 * sizeof(int));  // 如果失败,ptr变为NULL
// 此时原内存地址丢失,无法释放原内存

正确做法:

int *ptr = malloc(10 * sizeof(int));
// ... 使用ptr...

// 使用临时指针接收realloc结果
int *temp = realloc(ptr, 20 * sizeof(int));
if (temp) {
    // 成功:更新ptr指向新内存,原内存已自动释放
    ptr = temp;
} else {
    // 失败:temp为NULL,但ptr仍指向原内存
    // 此时可以根据需要继续使用原内存,或手动释放
    free(ptr);  // 如果不再需要原内存
    ptr = NULL;
}

关键区别:
  • 错误做法中,ptr直接被覆盖,原内存地址丢失
  • 正确做法中,使用temp暂存结果,失败时ptr仍可用


总结:不使用临时指针,在 realloc 失败时会导致原指针被置为 NULL,从而丢失对原内存块的引用,无法释放,造成内存泄漏。使用临时指针可以避免这个问题。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-12-19 05:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表