malloc分配数组需手动计算字节数,如malloc(10 * sizeof(int));必须用原始指针free;无法获知长度,须自行记录;c++中优先用std::vector或new[]/delete[]。

malloc分配数组内存时必须手动计算字节数
malloc不识别类型,只认字节大小。想分配一个包含10个int的数组,不能写malloc(10),得写malloc(10 * sizeof(int))。常见错误是漏乘sizeof,导致分配空间不足,后续写入越界——这时程序可能暂时不崩溃,但行为已未定义。
如果元素类型是自定义结构体,比如struct Node,同样要写malloc(n * sizeof(struct Node)),不能只用sizeof(Node)(缺少struct关键字在C中会编译失败,C++里虽可省略但显式写出更安全)。
建议始终把sizeof放在乘法左边,比如sizeof(int) * 10,避免整数溢出风险(虽然小数组几乎不会,但养成习惯能防大数组场景)。
free释放前必须确保指针来自malloc/calloc/realloc
用new或new[]分配的内存不能用free释放;反过来,malloc分配的也不能用delete。混用会导致堆损坏,典型现象是程序在后续某次malloc或free时崩溃,报错信息常含double free、corrupted size或invalid pointer。
释放前检查指针是否为NULL不是必须的(free(NULL)是安全的),但若指针已被释放过一次,再free就是双重释放。常见做法是释放后立即将指针置为NULL,比如:free(ptr); ptr = NULL;。
不要对数组中间某个地址调用free,比如free(ptr + 1)——只能传入当初malloc返回的原始指针值。
malloc分配的数组无法自动记录长度,需自行管理
malloc只返回起始地址,不保存分配了多少个元素。这意味着你无法从指针反推数组大小,sizeof(ptr)得到的是指针本身大小(通常是4或8字节),不是所指内存块大小。
实际使用中必须用额外变量存长度,例如:
int *arr = (int*)malloc(100 * sizeof(int)); size_t len = 100; // 必须自己记 // 后续遍历时用 len 控制边界,不能靠 ptr 推断
如果函数接收这种数组,通常需要同时传入长度参数,比如void process_array(int *arr, size_t len)。忽略这点容易导致缓冲区读写越界,尤其在做字符串操作或循环处理时。
C++里优先用new[]/delete[]或std::vector
虽然malloc/free在C++中合法,但它们绕过构造函数和析构函数。对于含非平凡构造函数的类类型(比如std::string成员),用malloc分配后直接赋值会导致对象未被正确初始化,行为未定义。
若坚持用动态数组,应选new int[100]配delete[];更推荐std::vector<int></int>,它自动管理内存、尺寸和异常安全,且支持移动语义。
只有在与C库交互、做底层内存池、或明确需要类型无关的原始内存块时,才考虑malloc。此时务必确认所有对象都是POD类型,且全程不依赖构造/析构逻辑。
最容易被忽略的一点:malloc失败时返回NULL,但C++默认不抛异常;如果忘了检查返回值,后续解引用空指针会直接崩溃。生产代码里,每次malloc后都该有if (!ptr) { /* handle error */ }。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











