2016-11-28 36 views
0

我是新的C++,我试图建立使用指针的指针的指针3维阵列时,段故障。我相信这样做有更有效的方法,但我现在正在尝试理解指针。阵列使用指针在C++:访问所述返回的数组

作为示例代码,我本来以下的一段,它工作得很好,分配,初始化和释放内存。

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(),我尝试访问三维阵列中的任何努力都是徒劳。

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); 
} 

当我编译此,“建设者”功能运行正常,但我得到一个分段错误,每当我尝试访问三维数组中的主要功能。我希望这个工作,因为我已经在我的书阅读,如果事情是通过参考使用指针传递给函数,该函数将不得不操纵它的力量。另外,我希望,我需要取消引用3D排列3次(即***频率),以正确地访问元素,但是编译器在我生气的努力这样做,脱口而出

myBuilder.cpp:42:17: error: indirection requires pointer operand ('int' invalid) cout << ***(frequencies[i1]+1) << endl;

我知道这是对于新手的问题,但任何帮助将不胜感激!

+5

我强烈建议你学会使用适当的C++容器('std :: vector','std :: array'等),而不是纯粹的C风格的数组和动态内存分配等 - 否则你只是抛弃C++的所有好处,你也可以用C语言编程。“ –

+1

*”如果某些东西是通过指针传递的,那么你的代码中带有manuel内存管理的指针业务表明你应该投资一本更好的书。 –

+1

我正在使用Dietel书。它并不鼓励我进行手动内存管理,但我只是好奇自己,想通过一个具有挑战性的例子(至少对我来说)更好地理解指针。 – Astaboom

回答

5

builderdestroyerfrequencies该指针是在该main指针freq拷贝。因此,设置它buildermain不改变(未初始化的)指针。你想要一个参考,而不是指针:

void builder(int aSize1, int aSize2, int aSize3, int***& frequencies); 

并为您的间接水平,注意,如果freqint***,然后freq[1]int**

1

在代码中,当你从调用builder(aSize1, aSize2, aSize3, freq); main()中,你逝去的int ***frequencies(包含自成立以来垃圾值),并希望这三重指针建设者函数调用中进行更新。

助洗剂功能分配存储器并更新生成器函数调用在以下代码行作为参数传递

frequencies = new int** [aSize1+1]; 

因此*** frequecny的拷贝,它是频率的指针,这是一个由呼叫值完成对构建器的调用后,未在main()中返回更新。它仍然包含垃圾地址,它会被访问以引起分段错误。

您需要将指针传递频率的地址,就像在构建器调用&频率并做出相应的变化生成器功能。