能否用sizeof()获取动态数组大小?C语言malloc实现realloc的疑问
能不能用sizeof()获取C语言动态数组的大小?
答案是绝对不行,你的老师在这里的说法有误。
核心原因
C语言中,sizeof()本质是编译期运算符(仅作用于变长数组VLA时是运行期,但VLA和动态分配数组不属于同一范畴):
- 对于静态数组(比如
int arr[10];),sizeof(arr)返回整个数组的字节数(例如10*4=40字节),因为此时arr的类型是int[10]。 - 但对于动态分配的数组(
malloc/calloc返回的指针,比如int *arr = malloc(10*sizeof(int));),arr只是一个普通指针,sizeof(arr)返回的是当前系统下指针本身的字节数(32位系统为4字节,64位系统为8字节),和你实际分配的内存大小完全无关。
反例代码验证
#include <stdio.h> #include <stdlib.h> int main() { // 分配能存10个int的动态数组 int *arr = malloc(10 * sizeof(int)); // 输出指针大小,而非数组实际占用的40字节 printf("sizeof(arr) = %zu\n", sizeof(arr)); free(arr); // 再分配能存100个int的数组 arr = malloc(100 * sizeof(int)); // 输出结果和上面完全一致,仍是指针大小 printf("sizeof(arr) = %zu\n", sizeof(arr)); free(arr); return 0; }
自己实现realloc的正确思路
标准库realloc能正确处理内存大小,是因为它内部维护了每个分配内存块的元数据(包括大小),但这些元数据对用户不可见。自己实现类似功能时,必须手动记录原数组的大小,步骤如下:
- 提前用变量保存原动态数组的字节数(比如
size_t old_size)。 - 根据新大小,调用
malloc分配新的内存块。 - 计算需要复制的字节数:若新大小小于旧大小,复制
new_size字节;反之复制old_size字节。 - 用
memcpy(或手动循环)复制数据,释放原内存块,返回新指针。
简单实现示例:
#include <stdlib.h> #include <string.h> void* my_realloc(void *ptr, size_t old_size, size_t new_size) { // 新大小为0,直接释放原内存并返回NULL if (new_size == 0) { free(ptr); return NULL; } // 原指针为NULL,等价于调用malloc if (ptr == NULL) { return malloc(new_size); } // 分配新内存 void *new_ptr = malloc(new_size); if (new_ptr == NULL) { return NULL; // 分配失败,保留原指针 } // 确定要复制的字节数 size_t copy_bytes = (old_size < new_size) ? old_size : new_size; memcpy(new_ptr, ptr, copy_bytes); // 释放原内存 free(ptr); return new_ptr; }
补充说明
部分编译器或系统提供了非标准函数(比如malloc_usable_size)来获取动态内存块的实际大小,但这不属于C标准范畴,无法保证跨平台可用,考试场景下也不会允许使用这类非标准接口。
内容的提问来源于stack exchange,提问作者PublicEnemy0
相关产品推荐
相关产品推荐

