-2

ive tried to debug the code however, it says that at sizes ptr[0][0][0][0][0][0] there is a segmentation fault and i cant seem to fix it, So this is just filler text i already told what i did and i dont know why there's a segmentation fault right at the start of the array. I am new to pointers and i have been stuck on this for a really long time

#include<iostream>
using namespace std;
void allocatememory(int******,int,int,int,int,int,int);
void fillArray(int******,int,int,int,int,int,int,int);

int main(){
int****** ptr;
allocatememory(ptr, 3,5,7,9,8,4);
fillArray(ptr, 3,5,7,9,8,4,20);
}

void fillArray(int****** ptr,int a,int b,int c,int d,int e,int f,int val){
int x=val;
for (int i = 0; i < a; i++)
{
    for (int j = 0; j < b; j++)
    {
        for (int k = 0; k < c; k++)
        {
            for (int l = 0; l < d; l++)
            {
                for (int m = 0; m < e; m++)
                {
                    for (int n = 0; n < f; n++)
                    {
                        ptr[i][j][k][l][m][n]=x;
                        x++;
                    }
                    
                }
                
            }
            
        }
        
    }
    
}
}



void allocatememory(int****** ptr,int a,int b,int c,int d,int e,int f){         //6 DMA
ptr=new int*****[a];
for (int i = 0; i < a; i++)
{
    ptr[i]=new int****[b];
    for (int j = 0; j < b; j++)
    {
        ptr[i][j]=new int***[c];
        for (int k = 0; k < c; k++)
        {
            ptr[i][j][k]=new int**[d];
            for (int l = 0; l < d; l++)
            {
                ptr[i][j][k][l]=new int*[e];
                for (int m = 0; m < e; m++)
                {
                    ptr[i][j][k][l][m]=new int[f];
                }
                
            }
            
        }
        
    }
    
}

}
  • 8
    Allocate a 1D flat array, write a help function to index into it. – Richard Critten Jun 15 '22 at 16:44
  • 12
    Congrats on being a [six star programmer](https://wiki.c2.com/?ThreeStarProgrammer)! – Kevin Jun 15 '22 at 16:45
  • 5
    You're headed down a rough path here. Not only is this hard to get right, it fragments the data structure to the point where the computer will probably spend more time chasing pointers and loading cache lines than it will doing the intended work. Take Richard's advice in the first comment. – user4581301 Jun 15 '22 at 16:50
  • @user4581301 the thing is, we did this in class and for practice purposes i wanted to do it at home, idk if its useful or not in the industry but as far as i am concerned right now i dont care if the computer gets slow or not i need to learn how to do this. One day i will also learn whatever way there is to make it fastr but for now i need to complete this first – King of the hill Jun 15 '22 at 16:52
  • When you're new to something, don't enter the Olympics. Start with two or three levels and make sure you have the book-keeping right. Then add a fourth, etc... – user4581301 Jun 15 '22 at 16:52
  • 4
    Assigning to a function's (non-reference) argument has no effect outside that function. There is nothing special about pointers (not even six layers of them). A much shorter example of the issue would be `void allocatememory(int* p) { p = new int; } int main() { int*p = nullptr; allocatememory(p); *p = 1; }` – molbdnilo Jun 15 '22 at 16:54
  • 3
    Just return the pointer from the function instead of passing an argument. – molbdnilo Jun 15 '22 at 16:54
  • 1
    `ptr`, in your `main` function, is uninitialized for its entire lifetime. You may need a (shudder) seventh star if `allocatememory` was supposed to modify the pointer passed from main. – Drew Dormann Jun 15 '22 at 16:54
  • 1
    @DrewDormann Or pass it as a `int******&` (man, that's scary). This is C++ after all... – Kevin Jun 15 '22 at 16:57
  • Learn about [C++ standard containers](https://en.cppreference.com/w/cpp/container) – Basile Starynkevitch Jun 15 '22 at 16:57
  • Here's another fun exercise idea once you get this beauty working - try deallocating the memory at the end of your program again ;) – Jane Doe Jun 15 '22 at 16:59
  • I would even start with a one dimensional structure, then add a second level and so on. After adding the second or third level, it will be obvious what the procedure for extending to higher dimensions is, which makes six levels completely pointless as an exercise. But anyhow, just to make sure you understand: Not only would you not use deeply nested pointers in any real program, you wouldn't use `new` at all. You should almost always use `std::vector`/`std::make_unique`/etc. instead. It is not something that is regularly used directly in modern C++. Keep that in mind after finishing the course – user17732522 Jun 15 '22 at 17:15
  • Given the [recent question from user Colson Baker](https://stackoverflow.com/questions/72633619/pointer-dma-allocation-through-function), I fear this `int****** ptr` horror may come from the instructor. Hopefully the 56,000 memory leaks will be addressed in a later lesson. – Drew Dormann Jun 15 '22 at 17:16
  • You could greatly simplify the `allocatememory` function by making use of templates: `void allocatememory(int*& out, int size) { out = new int[size]; } template void allocatememory(Element*& out, int size, Sizes...sizes) { out = new Element[size]; for (int i = 0; i < size; ++i) { allocatememory(out[i], sizes...); } }` – fabian Jun 15 '22 at 17:30
  • @Kingofthehill *we did this in class and for practice purposes i wanted to do it at home* -- Well, you are being told that no C++ programmer writes programs this way. So you're asking the people here to suspend all of their C++ training, and help you with an ill-advised endeavor. Does that sound fair? If you want six dimensions, then as mentioned create a single dimension, and figure out how to break down the six dimension to one, and in that, overload `operator()` to simulate array accesses. – PaulMcKenzie Jun 15 '22 at 17:37

1 Answers1

1

In the function main, in the line

fillArray(ptr, 3,5,7,9,8,4,20);

the pointer ptr is uninitialized. This means that you are passing an uninitialized pointer to the function fillArray. Therefore, the function fillArray causes a causing a segmentation fault when it attempts to derefererence this pointer.

You may think that you assigned a value to ptr in the line

ptr=new int*****[a];

of the function allocatememory, but the variable ptr in the function allocatememory is not the same variable as the variable of the same name in the function main.

In C++, there are three ways for a calling function to pass variables to the called function:

  1. by value
  2. by pointer
  3. by reference

You have written the function allocatememory in such a way that when calling the function, the pointer is passed by value, which means that a copy of the pointer is made. Therefore, when you assign a new value to this copy, the original variable is not modified. This is not what you want. You want the original variable to be modified instead. Therefore, you must pass this argument by pointer or by reference, instead of passing it by value.

In order to pass the variable ptr by reference, all you have to do is to add a & to the function signature of allocatememory:

void allocatememory( int******& ptr,int a,int b,int c,int d,int e,int f )

If you don't want to use references, then you can also pass the pointer by pointer (option #2), by changing the line

allocatememory(ptr, 3,5,7,9,8,4);

to

allocatememory(&ptr, 3,5,7,9,8,4);

and changing the function allocatememory to the following:

void allocatememory(
    int******* ptr_to_ptr,
    int a, int b, int c, int d, int e, int f
)
{
    int****** ptr = new int*****[a];

    //write pointer value to original variable
    *ptr_to_ptr = ptr;

    for (int i = 0; i < a; i++)
    {
        ptr[i]=new int****[b];
        for (int j = 0; j < b; j++)
        {
            ptr[i][j]=new int***[c];
            for (int k = 0; k < c; k++)
            {
                ptr[i][j][k]=new int**[d];
                for (int l = 0; l < d; l++)
                {
                    ptr[i][j][k][l]=new int*[e];
                    for (int m = 0; m < e; m++)
                    {
                        ptr[i][j][k][l][m]=new int[f];
                    }                
                }            
            }        
        }
    }
}

Note that I added an extra * to the declaration of ptr and renamed it to ptr_to_ptr. I also added a line to write the new value of the pointer to the original pointer ptr in main.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39