tags:

views:

93

answers:

3

I'm newbie. Pointer make my crazy T_T. Now, I'm do the socket programming project. This is my code.

typedef struct {
        char *ip[INET6_ADDRSTRLEN];
        char *username[20];
        time_t login_time;
        enum client_state client_state;
        int no_login;
    } Client;

    Client client[max_connections] = {}; // set to null
char remoteIP[INET6_ADDRSTRLEN];
.
.
.
.
.
if(client[new_fd-4] == NULL) {  // if fist attempt, client always null
   // I want to setting client[new_fd-4].ip = &remoteIP
   // How to write the code ??
}
+5  A: 

{} does not mean "null", it means "zero-initialized".

You can't put null values into the client array because client is an array of structs, and structs can't be null. If you want the client array to be able to contain "null" values, you need to make it an array of pointers to structs, e.g. Client* client[max_connection] = {};. This sets all the values in client to NULL because when talking about pointers, 0 and NULL are synonyms. When pointers aren't involved, this is not true because nothing other than a pointer can be null.

Note that since client will now contain pointers, you will have to allocate and deallocate the Client structs with malloc and free, e.g.

if(client[new_fd-4] == NULL) {  // if fist attempt, client always null
   client[new_fd-4] = malloc(sizeof(Client));
   client[new_fd-4]->no_login = 1; // For example. Note use of -> instead of .
}

And when you're done with some element client[i]:

free(client[i]);
client[i] = NULL; // Not strictly necessary, but a good idea

And I really doubt that you want to do this:

// I want to setting client[new_fd-4].ip = &remoteIP

I think what you really want is to copy the data contained in remoteIP into the ip member, like this:

memcpy(client[new_fd-4]->ip, &remoteIP, INET6_ADDRSTRLEN);
Tyler McHenry
I have a problem with line " memcpy(client[new_fd-4]->ip, ". Compiler warn me " ../src/server.c:362: warning: passing argument 1 of ‘memcpy’ makes pointer from integer without a cast ". After I run, it terminate after execute this line.
Atom Skaa ska Hic
Where you have `char*` as the type for `ip` and `username`, it should just be `char`. You want an array of characters for those members, not an array of character-pointers. I overlooked this mistake initially.
Tyler McHenry
Sorry, I forgot to set "char *ip[INET6_ADDRSTRLEN]; char *username[20];". It works now. But I found new problem, I just memcpy ip but 'ip' and 'username' change. IP : ::1username : ::1
Atom Skaa ska Hic
Sorry, It my mistake again. I forgot to initialize size of IP and username.
Atom Skaa ska Hic
+1  A: 

Update: Client client[max_connections] = {}; will create an array of Client objects whose all fields are initialized to zeros. So the check should be something like: if(client[new_fd-4].ip == NULL)

If remoteIP is a static array, or if it's a local array and client[new_fd - 4] won't be used after the current function is returned, you can just do:

client[new_fd - 4].ip = remoteIP;

Otherwise, you should assign memory and do a memcpy.

client[new_fd - 4].ip = malloc(INET6_ADDRSTRLEN);
strncpy(client[new_fd - 4].ip, remoteIP, INET6_ADDRSTRLEN);
Amarghosh
+1  A: 

I'm assuming that you didn't mean to define the ip structure member as an array of char*, nor the username structure member.

Try:

typedef struct {
    char ip[INET6_ADDRSTRLEN];
    // ...
 } Client;

And in the code:

strncpy(client[new_fd-4].ip, remote_ip, INET6_ADDRSTRLEN);
John Franklin