在 C++ 中使用指针的数组:访问返回的数组时出现分段错误
Posted
技术标签:
【中文标题】在 C++ 中使用指针的数组:访问返回的数组时出现分段错误【英文标题】:arrays using pointers in c++: segmentation fault when accessing the returned array 【发布时间】:2016-11-28 17:06:12 【问题描述】:我是 C++ 新手,我正在尝试使用指向指针的指针构建一个 3 维数组。我确信有更有效的方法可以做到这一点,但我目前正在尝试理解指针。
作为示例代码,我最初有以下部分,它工作正常,分配、初始化和释放内存。
void builder(int aSize1, int aSize2, int aSize3)
int i1, i2, i3;
int ***frequencies;
cout << "allocation started ..." << endl;
frequencies = new int** [aSize1+1];
for (i1=0; i1<=aSize1; i1++)
frequencies[i1] = new int*[aSize2+1];
for (i2 = 0; i2 <= aSize2; i2++)
frequencies[i1][i2] = new int [aSize3 + 1];
cout << "allocation done" << endl;
cout << " " << endl;
cout << "before initialization" << endl;
for (i1=0; i1<=aSize1; i1++)
for(i2=0; i2<=aSize2; i2++)
for(i3 = 0; i3 <= aSize3; i3++)
frequencies[i1][i2][i3]= (i1 * i2) % 10;
cout << "after initialization" << endl;
cout << " " << endl;
/* the "destroyer" part */
cout << "deleting ..." << endl;
for (i1=0; i1<=aSize1; i1++)
for(i2=0; i2<=aSize2; i2++)
delete [] frequencies[i1][i2];
for (i1=0; i1<aSize1; i1++)
delete [] frequencies[i1];
delete [] frequencies;
cout << "deleting done" << endl;
我想通过将上面的代码分成几个部分来提高赌注,这样我就可以在我的程序的main()
函数中使用初始化的数组(只是想看看我是否也可以在那里访问它们)。所以,我最终做了以下
头文件:
void builder(int aSize1, int aSize2, int aSize3, int*** frequencies)
int i1, i2, i3;
//int ***frequencies;
cout << "allocation started ..." << endl;
frequencies = new int** [aSize1+1];
for (i1=0; i1<=aSize1; i1++)
frequencies[i1] = new int*[aSize2+1];
for (i2 = 0; i2 <= aSize2; i2++)
frequencies[i1][i2] = new int [aSize3 + 1];
cout << "allocation done" << endl;
cout << " " << endl;
cout << "before initialization" << endl;
for (i1=0; i1<=aSize1; i1++)
for(i2=0; i2<=aSize2; i2++)
for(i3 = 0; i3 <= aSize3; i3++)
frequencies[i1][i2][i3]= (i1 * i2) % 10;
cout << **(frequencies[i1]+2) << endl;
cout << "after initialization" << endl;
cout << " " << endl;
void destroyer( int aSize1, int aSize2, int aSize3, int*** frequencies )
int i1, i2;
cout << "deleting ..." << endl;
for (i1=0; i1<=aSize1; i1++)
for(i2=0; i2<=aSize2; i2++)
delete [] frequencies[i1][i2];
for (i1=0; i1<aSize1; i1++)
delete [] frequencies[i1];
delete [] frequencies;
cout << "deleting done" << endl;
还有我的main()
,在那里我尝试访问 3d 数组,但徒劳无功。
int main()
int aSize1 = 10;
int aSize2 = 10;
int aSize3 = 10;
int*** freq;
builder(aSize1, aSize2, aSize3, freq);
cout << "builder finished" << endl;
cout << **(freq[1]+2) << endl;
destroyer( aSize1, aSize2, aSize3, freq);
当我编译它时,“builder”函数运行良好,但每当我尝试访问主函数中的 3d 数组时都会出现分段错误。我希望这能起作用,因为我在书中读到过,如果使用指向函数的指针通过引用传递某些内容,则该函数将有权操作它。另外,我预计我需要取消对 3d 数组的引用 3 次(即 ***freq)才能正确访问元素,但编译器因为我试图这样做而生气并脱口而出
myBuilder.cpp:42:17: 错误:间接需要指针操作数('int' 无效) cout
我知道这是一个新手问题,但我们将不胜感激!
【问题讨论】:
我强烈建议你学习使用正确的 C++ 容器(std::vector
、std::array
等)而不是简单的 C 样式数组和动态内存分配等 - 否则你只是在扔抛开 C++ 的所有优点,你还不如用 C 编程。
“如果使用指针通过引用传递某些内容” 并且代码中带有手动内存管理的指针业务表明您应该投资一本更好的书。
我正在使用 Dietel 的书。它不鼓励我进行手动内存管理,但我只是对自己很好奇,想通过一个具有挑战性的例子来更好地理解指针(至少对我来说)。
【参考方案1】:
builder
和destroyer
中的frequencies
指针是main
中freq
指针的副本。所以在builder
中设置它不会改变main
中的(未初始化的)指针。你想要一个对指针的引用:
void builder(int aSize1, int aSize2, int aSize3, int***& frequencies);
对于您的间接级别,请注意如果freq
是int***
,那么freq[1]
是int**
。
【讨论】:
【参考方案2】:在代码中,当您从 main() 调用 builder(aSize1, aSize2, aSize3, freq);
时,您传递的是 int ***frequencies
(自开始以来就包含垃圾值)并希望在构建器函数调用中更新此三元组指针。
构建器函数分配内存并更新在下面代码行中的构建器函数调用中作为参数传递的 ***frequecny 的副本
frequencies = new int** [aSize1+1];
因此,它是对频率指针的按值调用,在调用builder完成后不会在main()中更新返回。它仍然包含垃圾地址,被访问会导致分段错误。
您需要在构建器调用中传递频率指针的地址,如 &frequencies,并在构建器函数中进行相应的更改。
【讨论】:
以上是关于在 C++ 中使用指针的数组:访问返回的数组时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章
为什么在尝试将指向数组的指针作为函数的参数时出现访问冲突错误?
如何使用 ctypes 将数组从 C++ 函数返回到 Python