无法解引用指向数组的指针,函数返回数组指针后取值错误
核心问题
你遇到的是栈内存生命周期非法访问问题,本质错误如下:
- 函数
op_calculation中定义的unsigned int local[*(op_size_)]是栈上分配的局部数组,它的生命周期仅存续于op_calculation函数执行期间。 - 你通过
*op_ptr_array_ = &local[0]把栈内存地址返回给了上层main函数,当op_calculation执行结束后,对应的栈帧会被操作系统回收,这块内存的内容会被后续执行的其他代码(比如main里的std::cout调用)覆盖,虽然地址还是原来的数值,但指向的内容已经非法无效,所以读出来的值都是错的。 - 额外说明:你写的
unsigned int local[*(op_size_)]是C语言的变长数组(VLA)语法,标准C++本身不支持这种写法,只有部分编译器做了扩展支持,这个写法本身不具备可移植性。
修复方案
把局部数组的内存分配从栈改成堆,堆内存的生命周期由开发者手动控制,不会随函数退出自动销毁:
- 把
unsigned int local[*(op_size_)];替换成堆分配语句:unsigned int* local = new unsigned int[*(op_size_)]; - 数组用完后在
main函数末尾手动释放堆内存,避免内存泄漏:
delete[] ip_ptr_array; delete[] op_ptr_array;
修改后完整可运行代码
#include <iostream> void op_calculation(unsigned int* ip_ptr_array_, unsigned int ip_size_, unsigned int** op_ptr_array_, unsigned int* op_size_) { *(op_size_) = ip_size_ + 2; std::cout<<"op_size_ address: "<<op_size_<<std::endl; std::cout<<"op_size_ value: "<<*(op_size_)<<std::endl; // 栈分配改为堆分配,延长内存生命周期 unsigned int* local = new unsigned int[*(op_size_)]; std::cout<<"making local array to be pointed by op_ptr_array_\n"; for (unsigned int i = 0; i< *(op_size_); i++) { local[i]=i+1*3; std::cout<<local[i]<<" "; } std::cout<<"\n"; *op_ptr_array_ = &local[0]; local[3] = 87; // 用于校验指针特性 for (unsigned int i = 0; i < *(op_size_); i++) std::cout<<"array address: "<<&local[i]<<" ,op_ptr_array address: "<<(*op_ptr_array_)+i<<" ,val of array: "<<local[i]<<" ,val at op_ptr_array: "<<*((*op_ptr_array_)+i)<<std::endl; } int main() { unsigned int ip_size = 10; unsigned int* ip_ptr_array = new unsigned int[ip_size]; unsigned int op_size; unsigned int* op_ptr_array; for(unsigned int i = 0; i < ip_size; i++) { ip_ptr_array[i] = i+2*2; } op_calculation(ip_ptr_array, ip_size, &op_ptr_array, &op_size); std::cout<<"Value printing after operation of op_calculation function\n"; std::cout<<"op_size: "<<op_size<<std::endl; std::cout<<"op_ptr_array\n"; for(unsigned int i = 0; i < op_size; i++) std::cout<<"Address: "<<(op_ptr_array+i)<<" , Value: "<<*(op_ptr_array+i)<<"\n"; std::cout<<"\n"; // 手动释放堆内存,避免内存泄漏 delete[] ip_ptr_array; delete[] op_ptr_array; return 0; }
内容的提问来源于stack exchange,提问作者karim
相关产品推荐
相关产品推荐

