独立函数创建的数组末尾出现垃圾值的原因及解决方法
问题成因
你在arrCreate函数里定义的arr是栈上的局部数组——函数执行完毕后,它所在的栈帧会被销毁,这块内存会被系统回收或重新分配。返回这个数组的指针,本质上是返回了一个指向无效内存的悬垂指针。后续在printArr中访问这块内存时,读到的就是不确定的垃圾值(前几个偶尔显示0,只是因为栈内存还没被覆盖,但这属于未定义行为,绝对不能依赖)。
修复方案
既然要求在独立函数中创建数组,这里提供两种可行的解决办法:
办法1:动态内存分配(优先推荐)
通过malloc/calloc在堆上分配内存,堆内存不会随函数返回自动释放,使用完毕后需要手动调用free释放,避免内存泄漏:
#include <stdio.h> #include <stdlib.h> #define ARR_LEN 5 int* arrCreate(); void printArr(int* arr, int arrLen); int main(void) { int* arr = NULL; arr = arrCreate(); if (!arr) { // 必须检查内存分配是否成功 puts("内存分配失败"); return 1; } printArr(arr, ARR_LEN); free(arr); // 释放堆内存 arr = NULL; // 将指针置空,防止变成野指针 return 0; } int* arrCreate() { // calloc会自动将内存初始化为0,使用malloc的话需要手动调用memset初始化 return (int*)calloc(ARR_LEN, sizeof(int)); } void printArr(int* arr, int arrLen) { for (int i = 0; i < arrLen; i++) { printf("%d ", arr[i]); // 下标写法比指针偏移更直观 } }
办法2:使用静态局部数组
给数组添加static修饰符,这样数组会存储在静态存储区,函数返回后内存不会被释放。但要注意:静态数组是全局唯一的,多次调用arrCreate会复用同一块内存,容易出现数据被覆盖的问题,仅适合单场景使用:
#include <stdio.h> #define ARR_LEN 5 int* arrCreate(); void printArr(int* arr, int arrLen); int main(void) { int* arr = NULL; arr = arrCreate(); printArr(arr, ARR_LEN); return 0; } int* arrCreate() { static int arr[ARR_LEN] = { 0 }; // 加static让数组存放在静态存储区 return arr; } void printArr(int* arr, int arrLen) { for (int i = 0; i < arrLen; i++) { printf("%d ", arr[i]); } }
内容的提问来源于stack exchange,提问作者TiWl
相关产品推荐
相关产品推荐

