0

I'm trying to understand malloc but I keep getting "Segmentation fault: 11" with this piece of code:

#include <stdio.h> #include <stdlib.h> int main() { int i = 0, j = 0; char ** ptr = (char **) malloc(sizeof(char*)); for(i = 0; i < 5; i++) { for(j = 0; j < 10; j++) ptr[i][j] = 'a'; printf("%s\n", ptr[i]); } return 0; } 

I thought there wasn't enough bytes being allocated so I did malloc(sizeof(char*) * 100, but gives me the same error. What am I not understanding here?

8
  • 1
    ptr[i] is a pointer, but what does it point to ? Commented Sep 12, 2015 at 23:39
  • Does it not point to the beginning of the memory allocated? If I just do char * ptr = (char *) malloc(sizeof(char)) and take away the second loop statement, it works fine. Commented Sep 12, 2015 at 23:41
  • ptr does, but ptr[0] does not. Commented Sep 12, 2015 at 23:47
  • Do not cast the result of malloc & friends in C! Commented Sep 12, 2015 at 23:47
  • @Olaf What do you mean do not cast? I don't understand. Commented Sep 12, 2015 at 23:49

3 Answers 3

4

When you allocate a 2D array, you need to allocate the individual sub-arrays as well. In addition, you need to say how many elements you wish to have. For that you multiply the desired count by the number of elements, like this:

char ** ptr = (char **) malloc(5*sizeof(char*)); // Size=5 ---------------------^ for(int i = 0; i < 5; i++) { ptr[i] = malloc(11*sizeof(char)); // sizeof(char) is always 1, so the multiplication above is redundant. // You need 11 elements for ten characters for(int j = 0; j < 10; j++) { ptr[i][j] = 'a'; } // don't forget to null-terminate the string: ptr[i][10] = '\0'; printf("%s\n", ptr[i]); } 
Sign up to request clarification or add additional context in comments.

Comments

2

Your code is totally messed up in every aspect!

1) you allocated memory for exactly 1 Pointer to it. This means you can access ptr[0], but not ptr[1] ... ptr[4] as you are trying to do.

2) you never allocate anything for the elements in ptr[i].

3) you try to print a string a ptr[i] which is (even if your allocation would be right) never terminated.

4) although this is obviously only a beginners test, never forget to free your memory!!!!

To reach something CLOSE to what your sampel code is describing you could do:

int main() { int i,j; char ** ptr = malloc( 5 * sizeof(char*) ); /* an array of 5 elements of type char* */ for(i = 0; i < 5; i++) { ptr[i] = malloc( 11*sizeof(char) ); /* The element i of the array is an array of 11 chars (10 for the 'a' character, one for the null-termination */ for(j = 0; j < 10; j++) ptr[i][j] = 'a'; ptr[i][10] = '\0'; /* strings need to be null terminated */ printf("%s\n", ptr[i]); } // free your memory! for (i=0; i<5; i++ ) { free(ptr[i]); } free(ptr); return 0; 

6 Comments

Thanks, never knew about free(). I should use it once I'm done using any pointer initialized with malloc?
malloc "reserves" memory. If you don't free it, your program uses more and more memory, never giving it back to the operating system. Every "malloc()" should have a matching "free()" somewhere in the code. Also this isn't a real problem in your code, because the memory is released anyways as soon as the program terminates, you should learn this practice IMMEDIATELY. Whenever you call malloc, you should have a matching free. What/Where "matching" is depends on your code.
That makes sense. Thank you for all the info!
He cannot read through ptr[0] either as he has not initialized it. He allocated memory for lots of pointers but did not make them point anywhere.
@MarcoFreudenberger No, this answer says "This means you can access ptr[0], but not ptr[1] ... ptr[4] as you are trying to do." which is wrong.
|
-1

Another way to allocate the memory is:

char (*ptr)[11] = malloc( sizeof(char[5][11]) ); for(i = 0; i < 5; i++) { for(j = 0; j < 10; j++) ptr[i][j] = 'a'; ptr[i][10] = 0; printf("%s\n", ptr[i]); } free(ptr); 

It seems less hassle to use a single allocation than to use a lot of allocations, unless you have a pressing reason to do the latter.

2 Comments

a little oops. declared 11 pointers to char, but only set the first one.
@user3629249 no, this is 1 pointer to an array of 11 chars. You're describing char *ptr[11];

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.