I've been trying to print value of protent structure.
struct protoent {
char *p_name; /* official protocol name */
char **p_aliases; /* alias list */
int p_proto; /* protocol number */
}
My code, following List.c, shows proto.p_name = (null)
but It ends segmentation fault when it tries to print p_alliases
.
Does anyone tell me how it happens?
I think memory isn't allocated to p_alliases
pointer-to-pointer variable with memset
or proto = { 0 }
Then how can I memset to p_aliases
and print proto.p_aliases = (null)
?
List.c
#include <stdio.h>
#include <string.h>
#include <netdb.h>
int
main(){
struct protoent proto ;
memset(&proto,0,sizeof(proto));
printf("proto.p_name = %s\n",proto.p_name);
printf("proto.p_aliases = %s\n",*proto.p_aliases);
printf("proto.p_proto = %d\n",proto.p_proto);
}
The memset
statment below is setting all the memory allocated by proto
to 0
. So proto.p_aliases
is pointing to 0x000000
then you're tring to dereference it which leads to segmentation fault.
memset(&proto,0,sizeof(proto));
*proto.p_aliases
is the content of the adresse pointed to by proto.p_aliases
so you cannot print it as the adresse is NULL
. You can only print the adresse pointed to. So you have to change your print statment to:
printf("proto.p_aliases = %s\n", proto.p_aliases); // Not *proto.p_aliases
And because you're using the %s
formating it will print (null)
.
If you want to use memset
with *proto.p_aliases
then you have to allocate memory for it then proto.p_aliases
is no longer pointing to NULL
. In this case you can print. Then content of it's adresse.
proto.p_aliases = malloc(sizeof(char *));
memset(&(*proto.p_aliases), 0, sizeof(*proto.p_aliases));
printf("*proto.p_aliases %s", *proto.p_aliases);
You are trying to dereference a null pointer (ie the member char **p_aliases
).
Enclosed is a print_array
function that will safely print your array of strings, whether or not they have been assigned or freshly zeroed as in your example. The array is per the spec of protoent
(ie null entry terminating the list).
#include <stdio.h>
#include <string.h>
struct protoent {
char *p_name; /* official protocol name */
char **p_aliases; /* alias list */
int p_proto; /* protocol number */
};
// print char *array[], final entry (s[n]==null), handles empty list (s==null) also
void print_array(char **s) {
printf("[ ");
for (int i = 0; s && s[i]; ++i)
printf("\"%s\" ", s[i]);
printf("]\n");
}
int main(){
struct protoent proto ;
memset(&proto,0,sizeof(proto));
printf("With freshly zeroed struct:\n");
printf("proto.p_name = %s\n",proto.p_name);
printf("proto.p_aliases = ");
print_array(proto.p_aliases);
printf("proto.p_proto = %d\n",proto.p_proto);
char *aliases[] = { "A1", "A2", 0 };
proto.p_aliases = aliases;
printf("\nAfter assigning array:\n");
printf("proto.p_aliases = ");
print_array(proto.p_aliases);
}
Output:
$ ./nullstr
With freshly zeroed struct:
proto.p_name = (null)
proto.p_aliases = [ ]
proto.p_proto = 0
After assigning array:
proto.p_aliases = [ "A1" "A2" ]
I hope this is helpful.
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.