简体   繁体   中英

What's wrong with this simple code using strings, malloc and strcat?

A char** always confuses me. The following code generates a segmentation fault. Explain please...

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

int main()
{
    char** nameList;
    nameList = malloc(4*sizeof(char*));
    nameList[0] = malloc(12); //not sure if needed but doesn't work either
    nameList[0] = "Hello "; 
    printf("%s  ",nameList[0]);// even this statement isn't executed
    strcat(nameList[0], "World");
    printf("%s ",nameList[0]);
    return 0;
}

After nameList = malloc(4*sizeof(char*)); you have: nameList[0] = trash nameList[1] = trash nameList[2] = trash nameList[3] = trash

After nameList[0] = "Hello "; you have nameList[0] = "Hello" nameList[1] = trash nameList[2] = trash nameList[3] = trash

So when you do strcat(nameList[1], "World"); it's very likely you'll get a segfault, because nameList[1] can point to anywhere in memory.

Your code exhibits undefined behavior by writing to read-only storage, and also attempting to write past the end of it.

Your malloc idea was a step in the right direction. However, you should use strcpy to copy "Hello" into the newly allocated memory. In addition, you need to consider the size of the string that you are planning to append, and the null terminator when calculating the size of the dynamic allocation.

Obviously, you also need to free all your allocated memory at the end of your program:

char** nameList;
nameList = malloc(4*sizeof(char*));
nameList[0] = malloc(12);
strcpy(nameList[0], "Hello ");
printf("%s  ",nameList[0]);
strcat(nameList[0], "World"); // You were strcat-ing into a wrong element
printf("%s ",nameList[0]);
free(nameList[0]);
free(nameList);

Demo on ideone .

Before using double ptrs, get code that uses a single ptr to work. Also, you don't want to "overprogram" simple code. However, if you want to program the usage of a double ptr, start with this code and modify to use double ptrs.

int main()
{
        char *nameList;

        nameList = malloc(12);   // point nameList to 12 bytes of storage

        strncpy(nameList, "Hello \0", 7);
        printf("%s\n",nameList);   // notice no space, its already after hello

        strncat(nameList, "World", 5);
        printf("%s\n",nameList);

        free(nameList);

        return 0;
}

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