0

This is one of those annoying things where you know the answer is easy, but you just can't see it.

The printf statement in AllocIntArray shows that arrayPtr is correctly being assigned a memory location, however when the printf statement in main is run, it shows arrayB is still set to NULL.

Can someone show me what I am doing wrong when passing in arrayB to AllocIntArray?

#include <stdio.h>
#include <stdlib.h>

void AllocIntArray(int *arrayPtr, int numElements);

int main()
{
   int *arrayB = NULL;

   AllocIntArray(arrayB, 10);
   printf("Pointer: %p\n", arrayB);

   free(arrayB);

   getchar();
   return EXIT_SUCCESS;
}

void AllocIntArray(int *arrayPtr, int numElements)
{
   arrayPtr = (int *)malloc(sizeof(int) * numElements);
   printf("Pointer: %p\n", arrayPtr);

   if(arrayPtr == NULL)
   {
      fprintf(stderr, "\nError allocating memory using malloc");
      exit(EXIT_FAILURE);
   }
}
1
  • 1
    I think you arg arrayPtr should be pointer-to-pointer to be able to allocate and see outside it's function scope. so int **arrayPtr Commented Apr 26, 2011 at 12:40

5 Answers 5

4

Pass the double pointer.

#include <stdio.h>
#include <stdlib.h>

void AllocIntArray(int **arrayPtr, int numElements);

int main()
{
   int *arrayB = NULL;

   AllocIntArray(&arrayB, 10);
   printf("Pointer: %p\n", arrayB);

   free(arrayB);

   getchar();
   return EXIT_SUCCESS;
}

void AllocIntArray(int **arrayPtr, int numElements)
{
   *arrayPtr = malloc(sizeof(int) * numElements);
   printf("Pointer: %p\n", *arrayPtr);

   if(*arrayPtr == NULL)
   {
      fprintf(stderr, "\nError allocating memory using malloc");
      exit(EXIT_FAILURE);
   }
}
Sign up to request clarification or add additional context in comments.

4 Comments

+1, but I hesitated - please don't cast malloc return values.
@paxdiablo, isn't that just a matter of programmer preference?
@Chris, casting it can hide certain errors and warnings from the compiler, which will make your life more difficult. For example: faq.cprogramming.com/cgi-bin/…
When programming, never do things you don't know the reasons behind. Casting the result from malloc is one of those things. Most of the time people cast it without thinking because their C++ compiler gave a warning... that is, they are using the wrong compiler and hides it behind explicit type casts.
2

That's because arrayB is passed to AllocIntArray by value. Either pass it by reference (with a pointer-to-pointer), or better, return it from AllocIntArray:

int *AllocIntArray(int numElements)
{
   int *arrayPtr = malloc(sizeof(int) * numElements);
   printf("Pointer: %p\n", arrayPtr);

   if(arrayPtr == NULL)
   {
      fprintf(stderr, "\nError allocating memory using malloc");
      exit(EXIT_FAILURE);
   }
   return arrayPtr;
}

2 Comments

Another good way of doing it (especially if it avoids the problems most newbies have with indirect pointers. But, again, why are you casting the return from malloc?
@paxdiablo: I copy-pasted the OP's code and made minimal changes to it to demonstrate my intentions. Removed the malloc return cast as well.
0

You need to brush up a bit on parameter passing to functions.

The pointer you are sending to AllocIntArray is being copied into arrayPtr, The line

   arrayPtr = (int *)malloc(sizeof(int) * numElements);

assigns a value into the copy, and not the original variable, and therefore the original variable still points to nowhere.

First solution that comes to mind is to send a pointer to that pointer, but I think you'd best do some general brushing up on the matter of parameter passing before going much further.

1 Comment

I just haven't done much pointer to a pointer excercises in my class work so far, thus using it here eluded me. Once seeing it, it makes perfect sense.
0

arrayPtr is a pointer and the pointer is passed by value to the parameter. AllocIntArray can modify its version of arrayPtr but the changes won't be seen by main().

(Edit: if you're using C++) modifying the signature for AllocIntArray to change the type of arrayPtr to a reference ought to fix your problem.

void AllocIntArray(int *&arrayPtr, int numElements)

2 Comments

WTF is *&? You better not be trying to corrupt my beautiful C language with your C++ shenanigans :-)
Ahh... sorry. Tag my answer 'c++'.
0

The basic problem here is you are passing arrayB to AllocIntArray function as passed by value .In AllocIntArray its allocating memory properly and arrayptr is valid but in main function its not the same memory which you are expecting . This is the basic C programming concept and you can check bu adding print in both the function .

EX: I am sharing the difference between both problem and success case with below example .

/*Code with passed by value as a parameter*/ 
#include<stdio.h>
#include<stdlib.h>
void AllocateIntarray(int *arrayptr,int numElements)
{
     arrayptr = (int*) malloc(sizeof(int)*numElements);
     printf("Inside _func_AllocateIntarray_pointer:%p\n",arrayptr);

     if(arrayptr == NULL)
     {
         printf("ERR_MEM_ALLOCATION_FAILED:\n");
     }
}

int main()
{
     int *arrayB = NULL;
     AllocateIntarray(arrayB,10);
     printf("Inside _func_mainPointer:%p\n",arrayB);

     free(arrayB);
     return 0;
 }
/*Output :
 Inside _func_AllocateIntarray_pointer:0x55be51f96260
 Inside _func_mainPointer:(nil)*/

Code with Passed by reference and using double pointer .

#include<stdio.h>
#include<stdlib.h>
void AllocateIntarray(int **arrayptr,int numElements)
{
     *arrayptr =  malloc(sizeof(int)*numElements);
     printf("Inside _func_AllocateIntarray_pointer:%p\n",*arrayptr);

     if(*arrayptr == NULL)
     {
          printf("ERR_MEM_ALLOCATION_FAILED:\n");
     }
 }
 int main()
 {
     int *arrayB = NULL;
     AllocateIntarray(&arrayB,10);
     printf("Inside _func_mainPointer:%p\n",arrayB);

     free(arrayB);
     return 0;
  }
  /*Output :
    Inside _func_AllocateIntarray_pointer:0x562bacd1f260
    Inside _func_mainPointer:0x562bacd1f260*/

Comments

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.