网易首页 > 网易号 > 正文 申请入驻

realloc的双面真相:C语言动态数组的无声陷阱

0
分享至

【编者按】本文是C语言动态数组系列的第二篇。在上一篇中,我们构建了一个固定容量的数组,它在超出初始大小时直接罢工。今天,我们要解决一个更棘手的问题:如何让数组自动增长,而这背后的核心机制——realloc,可能是C标准库中最容易被误用的函数。 正文: 周三下午,一个C程序员写下了一行看似无害的代码:`arr->data = realloc(arr->data, new_size)`。他不知道的是,这行代码里藏着两个陷阱,任何一个都足以让程序在某个随机时刻崩溃,而且这种崩溃往往发生在代码审查通过很久之后。 此刻他的数组还好好的,但种子已经埋下。 这和上一步我们留下的那个固定容量数组形成鲜明对比。那个数组的问题很清楚:空间用完了,`array_push`返回-1,拒绝合作。用户要么提前知道需要多少空间,要么就得承担反复分配和拷贝的痛苦。这不是一个真正的动态数组,它只是一个带友好API的定长缓冲区。 真正的动态数组必须解决核心矛盾:调用者不知道自己需要存储5个元素还是500万个。 realloc就是为此而生的。它的函数签名简洁到具有欺骗性:`void *realloc(void *ptr, size_t new_size)`——传入一个已分配内存的指针,传回一个至少有新大小字节的内存块指针,旧数据原封不动。 但在这个简单接口背后,藏着两件完全不同的事。 第一种情况:原地扩展。如果在堆上你当前分配块的后面恰好有足够的空闲空间,内存分配器只需要把这个块的边界往后挪一挪。指针不变,没有新分配,没有拷贝。这是最快的路径,也是你永远不能指望的路径。 第二种情况:分配-拷贝-释放。如果当前块后面没有空间,分配器会找一块新的、足够大的内存区域,把旧数据全部拷贝过去,然后释放原来的块。指针会变,旧指针立刻失效。 这就是第一个陷阱的名字:指针失效。在realloc调用之后,任何指向旧缓冲区内部的指针都变成了悬空指针。这不是理论上的担忧,这是C代码库中最常见的use-after-free问题来源之一。当你写下`arr->data = realloc(arr->data, new_size)`时,如果realloc在内部执行了第二种情况,旧的内存已经被归还给操作系统,而你之前在数组里保存的那些指向特定元素的指针——它们现在全指向了已释放的内存。 更危险的是,这个bug可能很长时间都不会暴露。如果碰巧大多数时候realloc都在原地扩展,指针一直有效,测试通过,代码上线。然后在某个生产环境的特殊条件下,堆的布局变了,realloc决定搬家,程序开始随机崩溃。 但还有第二个陷阱,和失败处理有关。 realloc可能失败。当系统内存耗尽时,它会返回NULL。现在回到那行代码:`arr->data = realloc(arr->data, new_size)`。如果realloc失败返回NULL,NULL被赋值给了arr->data,而你原本的数据指针被覆盖了。结果是:旧数据的内存还在那里,但你已经丢了指向它的指针——内存泄漏了,数据也丢了。 解决这两个陷阱的正确方法是"临时指针"模式,它只有三行代码,但三行代码的区别就是:一个数组在内存耗尽时能体面降级,另一个会泄露数据然后崩溃。 这三行的逻辑很简单:先把realloc的结果存到一个临时变量里,检查它是不是NULL,如果不是,再把临时变量赋给arr->data。这样即使分配失败,arr->data仍然指向旧的有效数据,数组可以继续使用或体面地清理。 当你把这个临时指针模式应用到数组的自动扩容逻辑中时,整个机制就变得清晰:当size达到capacity,用realloc把缓冲区翻倍,检查是否成功,更新capacity计数,然后继续push。用户从头到尾都不需要关心capacity这个字段的存在,他们只需要调用push。 但用户不需要关心,不代表你不应该理解。自动增长带来了便利,也带来了代价。每次realloc可能搬家时,都是一次隐藏的拷贝操作。翻倍策略虽然摊销了拷贝的成本,但如果你提前知道需要存储100万个元素,一次性分配好仍然是更高效的选择。 动态数组的关键不在于"无限大",而在于"让容量管理从用户的责任变为数组自己的责任"。realloc是把这个转移变成现实的那一环,但前提是你得知道它的两面性:它可能移动你的数据,你绝不能把它的结果直接赋值给你正在重新分配的那个指针。 当你理解了这两点,大多数教程关于realloc的讲解就变成了明显的反例。你开始看懂那些看似无害的代码里藏着什么,也开始明白为什么C语言动态数组的实现总是围绕这个临时指针展开——不是因为它复杂,而是因为直接赋值的诱惑太自然了。


特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
入行前后判若两人,网约车司机活成这般模样

入行前后判若两人,网约车司机活成这般模样

网约车观察室
2026-06-03 21:41:43
老了才看透:父弱母强的家庭,养出来的孩子,大多是这两种结局

老了才看透:父弱母强的家庭,养出来的孩子,大多是这两种结局

心理观察局
2026-05-11 10:00:27
彭博社5月27日援引知情人士消息称,中国已暂停批准空客飞机交付

彭博社5月27日援引知情人士消息称,中国已暂停批准空客飞机交付

阿七说史
2026-06-02 15:54:32
中美打的不是贸易战、科技战和金融战,而是500年一遇的遭遇战

中美打的不是贸易战、科技战和金融战,而是500年一遇的遭遇战

深析古今
2026-06-03 16:25:18
县委书记被双规后,45岁副县长约书记19岁女儿爬山,说有要事相谈

县委书记被双规后,45岁副县长约书记19岁女儿爬山,说有要事相谈

秋风专栏
2025-04-15 17:16:42
猪油再次被关注!提醒:高血压患者常吃猪油,或会出现这几种变化

猪油再次被关注!提醒:高血压患者常吃猪油,或会出现这几种变化

芹姐说生活
2026-06-02 23:22:02
河南一家长咨询“戴牙套是否影响高考入场”,当地:可提前检测,没警报声不用管

河南一家长咨询“戴牙套是否影响高考入场”,当地:可提前检测,没警报声不用管

潇湘晨报
2026-06-03 19:00:16
厂家疯狂造大车,车位死守老标准,停不进出不来的死循环该破了!

厂家疯狂造大车,车位死守老标准,停不进出不来的死循环该破了!

电科技网
2026-06-02 08:00:10
3d今日独胆预测推荐号,第144期福彩3D试机号对应码预测开奖号

3d今日独胆预测推荐号,第144期福彩3D试机号对应码预测开奖号

大湾区娱乐官
2026-06-03 02:28:28
阅文约4亿元增持艺画开天28.22%股权,持股比例将升至59.7%

阅文约4亿元增持艺画开天28.22%股权,持股比例将升至59.7%

IT之家
2026-06-03 19:29:46
手机壳正在悄悄吃掉你的电池寿命

手机壳正在悄悄吃掉你的电池寿命

全栈遛狗员
2026-05-18 04:51:52
人民日报发文锐评《主角》,未曾点名张艺谋,却给张艺谋提了个醒

人民日报发文锐评《主角》,未曾点名张艺谋,却给张艺谋提了个醒

白面书誏
2026-06-03 14:43:26
光缆产品上游材料,高端光纤预制棒价格暴涨550%

光缆产品上游材料,高端光纤预制棒价格暴涨550%

财闻
2026-06-03 18:32:27
微软自己把Defender“够用论”悄悄撤了?

微软自己把Defender“够用论”悄悄撤了?

山月不知2
2026-06-03 01:38:58
43岁未婚官宣二胎,网友傻眼了:姐你糊涂啊……

43岁未婚官宣二胎,网友傻眼了:姐你糊涂啊……

英国那些事儿
2026-05-14 23:32:24
《动物城2》票房飙升至156亿,距《哪吒2》只差3亿,全球冠军不保

《动物城2》票房飙升至156亿,距《哪吒2》只差3亿,全球冠军不保

影视高原说
2026-06-02 18:05:41
狂飙!重庆或将迎来大动作!未来五年,这些两江要巨变了!

狂飙!重庆或将迎来大动作!未来五年,这些两江要巨变了!

王姐懒人家常菜
2026-06-03 18:23:49
没想到,“割四赔五”风波9天后,崔培军凭一番话,赚足农民口碑

没想到,“割四赔五”风波9天后,崔培军凭一番话,赚足农民口碑

削桐作琴
2026-06-02 20:05:30
剪不断理还乱!意媒:旺达向伊卡尔迪索要赡养费被法院驳回

剪不断理还乱!意媒:旺达向伊卡尔迪索要赡养费被法院驳回

可乐谈情感
2026-06-04 01:47:56
别被“某音”前凸后翘的网红骗了

别被“某音”前凸后翘的网红骗了

健身S叔
2026-03-22 11:12:04
2026-06-04 03:36:49
我是一个养虾人
我是一个养虾人
有态度网友ytd
4512文章数 42关注度
往期回顾 全部

科技要闻

传DeepSeek融资意向500亿:腾讯投100亿

头条要闻

男子不想上班辞职后上武当山当道士 8个月后选择下山

头条要闻

男子不想上班辞职后上武当山当道士 8个月后选择下山

体育要闻

选择中国品牌的库里,和他们的巨大野心

娱乐要闻

官方痛批乱象 刘涛郑恺等艺人遭点名

财经要闻

AI,开始偷懒了?

汽车要闻

专访蒋平:安全不做高低配 长安要让安全技术普惠

态度原创

时尚
本地
数码
艺术
房产

月经、初潮与生育真相,那些藏在动画片里的性启蒙

本地新闻

用杨柳青年画的方式,打开天津

数码要闻

高通CEO安蒙:“2026年是智能体之年”,Token成AI新货币

艺术要闻

二十年前割麦的场景

房产要闻

突发!254亩调规,海口江东的超级学校真的快来了!

无障碍浏览 进入关怀版