C代码编译成功却无法写入分配内存的原因分析
问题分析与修正
原代码的内存分配逻辑
main函数中定义空指针ptr_i,将它的地址传入alloc_arr函数(通过二级指针d_ptr接收)。alloc_arr调用malloc(2 * sizeof(int))分配可存储2个int的内存,再把分配的内存地址赋值给*d_ptr(即main里的ptr_i)。这部分逻辑本身没问题,但后续两个错误导致无法正确写入分配的内存。
两个关键错误
内存分配失败的判断错误
原代码中if (d_ptr == NULL)完全无效:d_ptr是main传入的&ptr_i,是有效的栈内存地址,永远不会为NULL。正确判断应检查malloc的返回值——也就是*d_ptr是否为NULL,因为malloc分配失败时会返回NULL。数组元素赋值的运算符优先级错误
C语言中[]优先级高于*,所以:*d_ptr[0]等价于*(d_ptr[0]),虽碰巧能赋值第一个元素,但写法逻辑错误;*d_ptr[1]等价于*(d_ptr[1]),实际是访问二级指针d_ptr偏移1位的栈内存(属于非法区域),写入操作会触发内存访问错误。
正确写法应为(*d_ptr)[0]和(*d_ptr)[1]——先解引用二级指针得到数组首地址,再用[]访问数组元素。
修正后的代码
#include <stdio.h> #include <stdlib.h> void alloc_arr(int **d_ptr); int main() { int *ptr_i = NULL; alloc_arr(&ptr_i); if (ptr_i == NULL) { printf("ptr_i null"); return 0; } printf("ptr_i address: %p, value at 0: %d, value at 1: %d\n", (void*)ptr_i, ptr_i[0], ptr_i[1]); // 释放内存避免泄漏 free(ptr_i); ptr_i = NULL; return 0; } void alloc_arr(int **d_ptr) { *d_ptr = (int *)malloc(2 * sizeof(int)); // 正确判断malloc是否成功 if (*d_ptr == NULL) { printf("cant allocate memory"); exit(1); } // 正确访问分配的数组元素 (*d_ptr)[0] = 15; (*d_ptr)[1] = 5; }
补充说明
- 用
%p打印指针地址是标准写法(原代码%x为非标准写法),并强制转换为void*符合格式要求; - 新增
free(ptr_i)释放内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者minhaz hosen
相关产品推荐
相关产品推荐

