18

I am getting an segmentation fault when I pass the double pointers to the function to initialize the memory

int main()
{
    double **A;
    initialize(A, 10, 10);
 ......
}

void initialize(double **A, int r, int c)
{
   A = (double **)malloc(sizeof(double *)*r);
   for(int i = 0; i< r; i++) {
        A[i] = (double *)malloc(sizeof(double) *c);
        for(int j = 0; j < c; j++) {
            A[i][j] = 0.0;
        }
   }
}

How can I pass the double pointers to the functions.....

1
  • That won't compile without changing initialize -- &A is a double***. Commented Dec 2, 2010 at 20:01

5 Answers 5

24

Like others have said, you need to take a pointer to pointer to pointer in your init function. This is how the initialize function changes:

void initialize(double ***A, int r, int c)
{
   *A = (double **)malloc(sizeof(double *)*r);
   for(int i = 0; i< r; i++) {
        (*A)[i] = (double *)malloc(sizeof(double) *c);
        for(int j = 0; j < c; j++) {
            (*A)[i][j] = 0.0;
        }
   }
}

And main will be:

int main()
{
    double **A;
    initialize(&A, 10, 10);
}

Also, the code as you posted it should cause no segmentation fault when passing the A pointer in. The segmentation fault most likely occurs when you return from the function and try to access A, because the A in main will not have been initialized. Only a copy of it is initialized the way you do it, and that copy is local to the initialize function, so it's lost when you return.

Sign up to request clarification or add additional context in comments.

3 Comments

@LVlad Hi, nice answer. Just revisiting my C: if you want to modify a pointer in C, you need to pass a pointer to a pointer. If you need to modify a pointer to a pointer, you need to pass a pointer to a pointer to a pointer. Why? So can we say, if we want to modify a value, we also need to pass a pointer to that value? Please explain more. Thanks in advance.
HI Unheilig, this is related to call by reference. For example (some type) *A then If there is need to modify some type at place other than where A is currently defined, you'll have to pass address of A and will require derefrencing the passed address in called function. The reason for passing address is that called function gets it's separate stack in process address space. In problem above, A defined in main() is in separate stack and is never accessed by initialize(). There is nothing wrong reported if A is not accessed back in main().
Thank you so much, I'm struggling with it for 3 days.
20

If you want to modify a pointer to pointer you need to pass a pointer to pointer to pointer.

void func(double ***data) { *data = malloc(sizeof(double*)*10); for.... };
double ** data; func(&data);

2 Comments

Just revisiting my C: if you want to modify a pointer in C, you need to pass a pointer to a pointer. If you need to modify a pointer to a pointer, you need to pass a pointer to a pointer to a pointer. Why? So can we say, if we want to modify a value, we also need to pass a pointer to that value? Please explain more. Thanks in advance.
To sum this up, one can say that if you want to modify a value inside a function, you need to pass the pointer to that value to the function. Values are (always) just copied (by value) to functions. Example/Reference
2

Well for one thing, the A inside initialize is a copy of the A in main -- so when you get back to main, its A is still uninitialized. If you try and use it -- boom!

To pass it to initialize 'by reference', you need to change the parameter type to double*** and pass in &A in main. Then, when you use it in initialize, you need to dereference it each time, i.e. *A.

Comments

1
  1. You are not checking for out of memory errors. Fail.

  2. You pass BY VALUE an uninitialized value A to initialize() and then initialize that. But back in main(), that local variable A is still uninitialized. Instead you might have initialize() return the double** (e.g. A = initialize(...)) or modify initialize() so its first formal parameter is a double ***pA that you initialize with *pA = (double**)malloc(...);

2 Comments

Re. (1), fair point, but how many toy programs like this have ever run out of memory?
Well, do you want to counsel beginners to check for out of memory conditions or do you want them to learn to write fragile software?No. If he wants A to be initialized as an out parameter of initialize(), he needs to pass in a double***, which is then used as (*pA) wherever A appeared in the original
1

This is the kind of thing you do not want to do. Instead of unnecessarily using an out argument for this, allocate in the function and return the result. Do this instead:

int main() 
{
    double **A;
    A = initialize(A10, 10);
}

double** initialize(int r, int c)
{
   double **A;
   A = malloc(sizeof(double *)*r);
   for(int i = 0; i< r; i++) {
        A[i] = (double *)malloc(sizeof(double) *c);
        for(int j = 0; j < c; j++) {
            A[i][j] = 0.0;
        }
   }
  return A;
}

1 Comment

You forgot to update the return type of initialize, and to actually return a value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.