2

Hi I ran in to this situation. I am using malloc to give me an array of 10 pointers. When I see the test pointers in gdb, one of them(the third )points to 0x0. Sometimes the code segfaults when using apple[2]->string = "hello". Why does malloc do this? Thanks in advance for the help.

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


int
main(void)
 {
  typedef struct test
    {
      char *string;
      int data;
    } test;

   test *apple[10];  // Declare an array of 10 test pointers. This line results in one of  the  pointers having a null value.
   apple[0] = malloc(sizeof(test));
   apple[0]->string = "hello";

   printf("The string is %s\n",apple[0]->string);
   printf("Size of apple[0]->data is %d\n",sizeof(apple[0]->data));
   printf("Size of tester is %d\n",sizeof(test));
   free(apple[0]);
   return 0;

 }

I wanted to see how the array of pointers would work. I was not intending on using all the 10 pointers. So do I need to malloc only what I need? Is it a coincidence, that the third pointer was 0x0?

kevin
  • 173
  • 3
  • 10

3 Answers3

5

Memory has only been allocated for first element in apple so only apple[0] points to a valid struct test.

To allocate memory for all elements of apple:

for (int i = 0; i < sizeof(apple) / sizeof(test*); i++)
{
    apple[i] = malloc(sizeof(test));
}

Similar loop required to free().

test.string is a char*, so pointing to a string literal as you have done is fine (though type should be const char*). If you wish to copy a string to test.string then you must malloc() space to copy into and free() it later.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • Yes, uninitialised memory can hold any value. Only `malloc()` what you need but you need a way to know what you have malloc'd, setting all unmalloc'd elements to `NULL` for example: `test *apple[10] = { 0 };`. – hmjd Jan 22 '12 at 11:56
2

There are different approaches, depending on what your final goal is.

If the number of elements in your array is meant to be constant every time the program is run, you don't have to use pointers at all:

test apple[10]; // array with 10 instances of test

test[0].string = ...;
test[1].data = ...;

If you'd like to use your approach (with pointers, which isn't really necessary right now), you have to malloc() every element on its own (like you did with apple[0], or malloc() the whole array:

int num = 10;
test *apple = malloc(sizeof(test) * num);

// access any element here
apple[5].string = "hello!";

free(apple);
Mario
  • 35,726
  • 5
  • 62
  • 78
1

You are allocating only one instance of the test and you're assigning it to the first array element:

apple[0] = malloc(sizeof(test));

To allocate all ten, you'd do:

for (int i = 0; i < 10; i++) {
    apple[i] = malloc(sizeof(test));
}
DarkDust
  • 90,870
  • 19
  • 190
  • 224