简体   繁体   English

c ++中使用指针的数组:访问返回的数组时出现分段错误

[英]arrays using pointers in c++: segmentation fault when accessing the returned array

I'm new to C++ and I'm trying to build a 3 dimensional array using a pointer to a pointer to a pointer. 我是C ++的新手,正在尝试使用指向指针的指针构建3维数组。 I am sure there are more efficient ways in doing so, but I am trying to understand pointers at the moment. 我确信这样做有更有效的方法,但是我现在正在尝试理解指针。

As example code, I originally had the following piece, which worked fine, allocating, initializing, and releasing the memory. 作为示例代码,我最初有以下代码,可以很好地工作,分配,初始化和释放内存。

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;

}

I wanted to up the ante by splitting the code above into several parts, so that I could use the initialized array in the main() function of my program (just to see if I can access them there as well). 我想通过将上面的代码分成几部分来提高赌注,以便可以在程序的main()函数中使用初始化的数组(只是看看是否也可以在其中访问它们)。 So, I ended up doing the following 所以,我最终做了以下事情

The header file: 头文件:

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

and my main() where I try to access the 3d array in a fruitless effort. 和我的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);
}

When I compile this, the "builder" function runs fine, but I get a segmentation fault whenever I try to access the 3d array in the main function. 当我对此进行编译时,“生成器”功能运行良好,但是每当我尝试访问main函数中的3d数组时,都会遇到分段错误。 I would expect this to work because I have read it in my book that if something is passed by reference using a pointer to a function, the function would have the power to manipulate it. 我希望它能奏效,因为我在书中已经读过,如果使用指向函数的指针通过引用传递了某些东西,则该函数将具有操纵它的能力。 Also, I expected that I would need to dereference the 3d array 3 times (ie ***freq) in order to correctly access the elements, but the compiler gets mad at me for trying to do so and blurts out 另外,我希望我需要将3d数组取消引用3次(即*** freq)才能正确访问元素,但是编译器因为尝试这样做而生气,并脱口而出

myBuilder.cpp:42:17: error: indirection requires pointer operand ('int' invalid) cout << ***(frequencies[i1]+1) << endl; myBuilder.cpp:42:17:错误:间接要求指针操作数('int'无效)cout << ***(frequencies [i1] +1)<< endl;

I know this is a newb question, but any help will be appreciated! 我知道这是一个新问题,但是任何帮助将不胜感激!

The frequencies pointer in builder and destroyer is a copy of the freq pointer in main . frequencies在指针builderdestroyer副本 freq在指针main So setting it in builder does not change the (uninitialized) pointer in main . 因此,在builder中设置它不会更改main的(未初始化)指针。 You want a reference to pointer instead: 您需要引用一个指针:

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

And for your levels of indirection, note that if freq is an int*** , then freq[1] is an int** . 并且对于您的间接级别,请注意,如果freqint*** ,则freq[1]int**

In code when you call builder(aSize1, aSize2, aSize3, freq); 在代码中调用builder(aSize1, aSize2, aSize3, freq); from main(), you are passing int ***frequencies (that contains garbage value since its inception) and want this triple pointer to be updated within builder function call. 从main()中,您正在传递int ***frequencies (自创建以来就包含垃圾值),并希望在构建器函数调用中更新此三重指针。

The builder function allocates memory and updates a copy of ***frequecny passed as parameter in builder function call in below code line 构建器函数分配内存并更新下面代码行中的构建器函数调用中作为参数传递的*** frequecny的副本

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

Thus, it is a call by value for frequency pointer, which is not returned updated in main() after completion of call to builder. 因此,这是对频率指针的按值调用,在完成对builder的调用之后,不会在main()中更新更新返回该指针。 It still contains garbage address in it that gets accessed to cause you segmentation fault. 它仍然包含垃圾地址,该地址会被访问以引起分段错误。

You need to pass the address of frequencies pointer like &frequencies in builder call and make the changes accordingly in builder function. 您需要在构建器调用中传递频率指针的地址(例如&frequency),并在构建器函数中进行相应的更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM