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.