1

Following code is printing protoent structure.

Unless I do getprotoent() I can’t print structure variable although I initialize it.

It ends segmentation falter if I don’t getprotoent().

Does anyone know this?

Samle.c

#include <stdio.h>
#include <string.h>
#include <netdb.h>
int
main(){
        struct protoent *proto;
        memset(&proto,0,sizeof(proto));
        proto = getprotoent();

        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);
}
user1345414
  • 3,745
  • 9
  • 36
  • 56
  • 1
    cause without getprotoent, you have not assign any memory to the structure pointer. – Ishmeet Dec 20 '13 at 08:58
  • 1
    The `memset` is simply `proto = NULL`, so it's a waste of time. – Devolus Dec 20 '13 at 08:59
  • 1
    `*proto` is just a pointer, you never "initialize" it, of course you get segment fault trying to dereference it. You need to malloc memory for it, what is most likely being done in getprotoent(). – moeCake Dec 20 '13 at 08:59
  • 1
    Where is `getprotoent()`? – Devolus Dec 20 '13 at 09:00
  • 3
    Also please use `x->` instead of `(*x).` – user703016 Dec 20 '13 at 09:00
  • @Purrfection : Just for my knowledge, why `x->` is better than `(*x).`? What I know is both are same and can be used alternately, though the first way is more readable. – 0xF1 Dec 20 '13 at 09:05
  • @0xF1 You just answered your own question :) Shorter to type and more readable. – user703016 Dec 20 '13 at 09:06
  • Thanks @Purrfection I thought it is some kind of UB or some compatibility issue (which of course, I am not aware of). :-) – 0xF1 Dec 20 '13 at 09:09

3 Answers3

3

You should use:

struct protoent proto;
memset(&proto,0,sizeof(proto));

As *proto is a pointer to structure, it can just hold the address of a variable of struct protoent type. Your statement doesn't actually initializes the structure.

More Explanation:

struct protoent *proto;
memset(&proto,0,sizeof(proto));

On some system, this may be same as struct protoent *proto = NULL;

Since you are actually "assigning 0 to the pointer"

After that you are dereferencing it in printf statement, that will surely cause seg fault.

EDIT/UPDATE: Suggested by user694733 in the comments

Not all system assign address 0 to the NULL pointer. It is a translation to some address reserved as NULL which is done by compiler when you do <datatype> *ptr = 0;. However doing memset(&ptr,0,sizeof(ptr)); will not be understood by compiler as NULL assignment on these systems and it will simply assign address 0 to ptr which as I said may not be a NULL.

For more understanding, Please read this link or the complete C-FAQ chapter about NULL pointers.

I would also like to cite this related answer on SO.

Community
  • 1
  • 1
0xF1
  • 6,046
  • 2
  • 27
  • 50
  • 1
    `memset` does *not* equal `proto = NULL;` on all systems. – user694733 Dec 20 '13 at 09:11
  • @user694733 : Please can you explain that with some example? because I believe that if `NULL` is `#defined` as `0`, then that will always be true. – 0xF1 Dec 20 '13 at 09:13
  • True, but compiler does conversion to real value if necessary for the system. `memset` on the other hand happens at runtime. See [the C FAQ question 5.5](http://c-faq.com/null/machnon0.html). The whole chapter 5 of the faq explains NULL pointers in detail. – user694733 Dec 20 '13 at 09:16
2

The call to memset is the same as if you would do

proto = 0; // Which is not neccessarily the same as NULL.

It doesn't allocate memory, it just initializes the pointer.

If you want to derference the pointer, you have to assign it some valid memory, which apparently getprotoent() is allocating. Dereferencing the NULL pointer would cause the program to abort which is correct.

Devolus
  • 21,661
  • 13
  • 66
  • 113
1

You are doing

//this defines pointer variable
struct protoent *proto;  

//this does not allocate memory for the pointer variable
memset(&proto,0,sizeof(proto)); 

So whenever you dereference it without allocating it or calling getprotoent, it will fail.

Rohan
  • 52,392
  • 12
  • 90
  • 87