简体   繁体   中英

C malloc (Segmentation fault: 11)

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?

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]);
}

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;

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM