简体   繁体   中英

realloc: Segmentation fault

Take the following code,which is in ac :

struct header {
    char **name;
};
int main(void)
{
    int i=0;
    char **p;
    struct header h;
    char tmp[10];
    memset(&h, 0, sizeof(h));

    for(i=1;i<10;i++){
        sprintf(tmp, "name%d", i); 
        p = realloc(h.name, sizeof(char*)*i);
        printf("h->name=%p, p=%p\n", h.name, p); 
        h.name = p;
        h.name[i-1] = malloc(100);
        strncpy(h.name+i-1, tmp, strlen(tmp));
        printf("h->name=%s\n", h.name+i-1);
    }   
    return 0;
}

after i gcc ac and ./a.out ,following error happends: Segmentation fault I have no any idea about this,what exactly this happen?

EDIT1: found the qustion! strncpy(h.name+i-1, tmp, strlen(tmp)) should strncpy(h.name[i - 1], tmp, strlen(tmp) + 1) and this qustion can be found through gcc warnings:/usr/include/string.h:131:14: note: expected 'char * __restrict__' but argument is of type 'char **' ,so silly! thanks to everyone!

strncpy(h.name+i-1, tmp, strlen(tmp)); doesn't null terminate the destination string. It may be that the next printf() crashes trying to print it.

I suspect you're compiling on a 64 bit system, and don't have:

#include <stdlib.h>

at the top of your file. You should get a warning about this when you compile:

incompatible implicit declaration of built-in function 'malloc'

As Michael Burr points out, you're also not terminating the string correctly.

You should be able to find out where it is crashing by compiling with -g and running it through a debugger (eg gdb).

The problem is that your strncpy is only strlen(tmp) so if temp is name5, strlen(tmp) == 5, which doesn't copy the NULL that your sprintf put on. You need to do strlen(tmp)+1 to copy in the NULL.

http://linux.die.net/man/3/strncpy

Also, it's odd that h.name is a double pointer to char. If it should be a string, it should just be a char *. It is then weird that you're only mallocing space for your array of single pointers to one entry.

'\\0' of a string is not the whole thing.although you need

strlen(tmp)+1 

but the main error is that you didn't dereference your char** pointer like this:

strncpy(*(h.name+i-1), tmp, strlen(tmp)+1);
printf("h->name=%s\n", *(h.name+i-1));

this below will work, and I have tested it by my gcc:

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

struct header {
char **name;
};

int main(void)
{
    int i=0;
    char **p;
    struct header h;
    char tmp[10];
    memset(&h, 0, sizeof(h));

    for(i=1;i<10;i++){
        sprintf(tmp, "name%d", i);
        //printf("tmp:%s\n",tmp);
        p = realloc(h.name, sizeof(char*)*i);
        printf("h->name=%p, p=%p\n", h.name, p);
        if(p==NULL) {
            printf("realloc failed.\n");
            return -1;
        }
        h.name = p;
        h.name[i-1] = (char *)malloc(100);
        strncpy(*(h.name+i-1), tmp, strlen(tmp)+1);
        printf("h->name=%s\n", *(h.name+i-1));
    }   
    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