C语言中如何避免返回指向局部变量的指针?
问题:返回局部数组指针引发编译警告的解决办法
代码示例
int* income(int ticket_count, int dailyticket_count) { int* p; p = (int*)malloc(sizeof(int)); int sum[ticket_count+dailyticket_count+1]; p = &sum[0]; int cnt = 0; for ( int i = 0; i < dailyticket_count; ++i) { sum[i] = 600; cnt++; } int cnt2 = cnt; for (int l = cnt ; l < dailyticket_count+ticket_count; ++l) { sum[l] = 1300; cnt2++; } sum[cnt2+1] = 0; return p; }
问题说明
希望返回指向sum数组起始位置的指针p,函数内部打印*p、*p+1等内容时运行正常,但编译时出现“返回指向局部变量的指针”的警告,需解决该问题。
解决方法
问题根源
sum是栈上的局部数组,函数执行完毕后栈帧销毁,局部变量内存会被释放或重新分配。此时返回的指针指向的是无效内存,后续使用会导致未定义行为,编译警告正是在提示这个风险。
此外代码还有两处问题:
- 初始
malloc分配的1个int内存未被使用,直接将p指向sum,造成内存泄漏; sum[cnt2+1] = 0;存在越界风险——cnt2最终等于ticket_count + dailyticket_count,而sum的合法索引范围是0到ticket_count + dailyticket_count,cnt2+1超出了这个范围。
可行解决方案
方案1:动态内存分配(推荐)
将栈上的局部数组改为malloc分配的堆内存,堆内存不会随函数返回释放,需调用方后续用free释放:
int* income(int ticket_count, int dailyticket_count) { int total = ticket_count + dailyticket_count; // 分配足够内存,+1用于存储终止的0 int* sum = (int*)malloc(sizeof(int) * (total + 1)); if (sum == NULL) { // 必须检查内存分配是否成功 return NULL; } int cnt = 0; for (int i = 0; i < dailyticket_count; ++i) { sum[i] = 600; cnt++; } for (int l = cnt; l < total; ++l) { sum[l] = 1300; } sum[total] = 0; // 修正越界问题 return sum; }
调用方使用示例:
int* result = income(5, 3); // 使用result处理数据... free(result); // 用完必须释放内存
方案2:调用方提供数组
让调用方提前分配好数组,将指针传入函数,避免动态内存管理:
void income(int ticket_count, int dailyticket_count, int* sum) { int cnt = 0; for (int i = 0; i < dailyticket_count; ++i) { sum[i] = 600; cnt++; } int total = ticket_count + dailyticket_count; for (int l = cnt; l < total; ++l) { sum[l] = 1300; } sum[total] = 0; }
调用方使用示例:
int ticket_num = 5, daily_num = 3; int sum_arr[ticket_num + daily_num + 1]; income(ticket_num, daily_num, sum_arr); // 直接使用sum_arr即可
方案3:静态数组(不推荐)
将sum定义为static int sum[...],静态变量存储在全局内存区,函数返回后不会被销毁。但该方法存在线程安全问题,且C99变长数组无法用static修饰,仅适合固定大小数组的场景,不推荐在本代码中使用。
内容的提问来源于stack exchange,提问作者FireFalcon3469
相关产品推荐
相关产品推荐

