0

I help teach C in a beginners class. We were covering the use of malloc for dynamic memory allocation and a student wanted to place a wrapper around malloc. I'm not sure if this would ever be useful but playing around with stuff is the best way to learn.

However when the student tried to aplocate memory for an array via their malloc wrapper function it didn't work - Segmentation fault.

A minimum example is given below.

#include <stdlib.h> 

void mallocWrapper(int *intArray, int length){

    intArray = malloc(length * sizeof(int));
}

int main() { 

    int *array;
    int arraySize = 10;

    mallocWrapper(array, arraySize);

    // this line causes the Segmentation fault  
    array[0] = 0;

    return 0; 
} 

As far as I understood the array variable would just become the address of the first point in memory which had been reserved for the array. I assumed this would be the cases regardless of where the memory was allocated i.e. in the main or in mallocWrapper.

As a result I didn't know what to tell the student other than I would get back to them.

Any help would be appreciated. Thanks

Andy T
  • 337
  • 1
  • 2
  • 14

4 Answers4

5

If you want to change the caller's array member, you need to pass a pointer to it. i.e. you need to pass a pointer to a pointer into mallocWrapper.

void mallocWrapper(int **intArray, int length){
    *intArray = malloc(length * sizeof(int));
}

mallocWrapper(&array, arraySize);

Or, better, you could change mallocWrapper to return the newly allocated memory instead.

void* mallocWrapper(int length){
    return malloc(length * sizeof(int));
}

array = mallocWrapper(arraySize);
simonc
  • 41,632
  • 12
  • 85
  • 103
  • 2
    The second approach is the way to go. Wrapping `malloc()` and changing the calling "style" seems very unfriendly. – unwind Nov 29 '13 at 09:25
  • Of cause - I should have spotted that... I was in the mind set that pointers pass by reference and forgot than here I wanted to change the actual pointer address, not what was in that address. Thanks for the reply. And I agree the second approach is best due to keeping with the malloc 'style' as mentioned in other posts. – Andy T Nov 29 '13 at 09:40
1

You are passing copy of the pointer array to the function, hence whatever modified inside the function is not reflected outside. You need to change the signature of the function to void mallocWrapper(int **intArray, int length) and use *intArray = ..... for it to work.

Naveen
  • 74,600
  • 47
  • 176
  • 233
1

Use like:

void mallocWrapper(int **intArray, int length)
{
    *intArray = malloc(length * sizeof(int));
}

int main()
{

    int *array    = NULL;    //Whenever you declare a pointer assign it to NULL
    int arraySize = 10;

    mallocWrapper(&array, arraySize);

    array[0] = 0;
    return 0;
}
Midhun MP
  • 103,496
  • 31
  • 153
  • 200
0

In C, function parameters are passed by value. This helps program stability as it's less easy to modify unintentionally a variable in the function caller.

In your case, intArray = malloc(length * sizeof(int)); does not change value the of the pointer array in main() so you get undefined behaviour as you are dereferencing an uninitialised pointer (via the almost functionally equivalent array notation).

Passing a pointer to the pointer is one approach:

void mallocWrapper(int** intArray, int length){...

mallocWrapper(&array, arraySize);

as is modifying the function to return the new pointer.

But, I would discourage stubbing standard C library functions in this way as it makes a program more difficult to read and debug: if I see a call to malloc then I know exactly what to expect. If I see mallocWrapper I have no idea what to expect until I read the documentation or the function source code itself.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Good explanation. I understand it is a strange non-standard thing to do. It was just a student messing around as mentioned. – Andy T Nov 29 '13 at 09:35
  • 2
    Of course @Andy T; but I frequently encounter professional code full of stubs and wrappers and I'm relying on you to use your position to eliminate this problem at source ;-) – Bathsheba Nov 29 '13 at 09:37