user1324258
user1324258

Reputation: 561

array of structs in struct

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


typedef struct user {
    char *username;
    struct sockaddr_in addr;
} user;

user* users;

typedef struct room
{
  char *roomname;
  user* users;
} room;

room* rooms;

int addToUsersArray(char *username) {
    int i = 0;

    for(; i<10; i++) {
            if(users[i].username=='\0') {
                    users[i].username = username;
                return 1;
            } else if(strcmp(users[i].username, username) == 0)
                return -1;
    }
    return -1;
}


void initUsersArray() {  
    users = (user*) calloc(10, sizeof(user)); 
}

void initRoomsArray() {  
rooms = (room*) calloc(10, sizeof(room));
    int i =0;   
    for(;i<10;i++)      
         rooms[i].users = (user*) calloc(10,sizeof(user));  
}

int addToRoomsArray(char *roomname) {
    int i = 0;

    for(; i<10; i++) {
            if(rooms[i].roomname=='\0') {
                    rooms[i].roomname = roomname;
                return 1;
            } else if(strcmp(rooms[i].roomname, roomname) == 0)
                return -1;
    }
    return -1;
}

int addUserToRoom(char *roomname, user usr) {
    int i = 0;
    int k = 0;

    for(; i<10; i++) {
            if(rooms[i].roomname=='\0') {
                    rooms[i].roomname = roomname;
                    return 1;
            } else if(strcmp(rooms[i].roomname, roomname) == 0) {
            for(;k<10;k++) {
                if(rooms[i].users[k].username==NULL) { //This line makes trouble
                    rooms[i].users[k] = usr;
                }
            }
        }

    }
    return -1;
}


int main(int argc, char** argv) {
    initUsersArray();  
    initRoomsArray();      
    char *username = "Max";
    addToUsersArray(username);
    username = "Ma1x";
    addToUsersArray(username);
    printf("%s\n",users[0].username);
    printf("%s\n",users[1].username);

struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(4444);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");  

char *room = "sportchat";
addToRoomsArray(room);
room = "berlinchat";
addToRoomsArray(room);

    printf("%s\n",rooms[0].roomname);
    printf("%s\n",rooms[1].roomname);

user michi;
michi.username = "michi";
michi.addr = addr;

struct sockaddr_in addr2;
    addr2.sin_family = AF_INET;
    addr2.sin_port = htons(1234);
    addr2.sin_addr.s_addr = inet_addr("127.0.1.1");

user willi;
willi.username = "willi";
willi.addr = addr2;

addUserToRoom(room,michi);
addUserToRoom(room,willi);


    return 1;
}

When running addUserToRoom(room,michi) i get a segmentation fault. I am still a little bit unsure with using structs. When commenting out rooms[i].users[k] = usr; the segmentation fault disappears. I am using gcc on an unix system. Does gcc analyse an if-expression with an empty block?

EDIT How do i implement a variable number of users and rooms? I think i have to use realloc. But how? Regards

Upvotes: 0

Views: 1682

Answers (2)

Johan
Johan

Reputation: 41

There are several issues with that code. To answer the question, you haven't allocated the rooms[i].users array.

Upvotes: 0

zmo
zmo

Reputation: 24812

you never allocate memory, neither initialize

room.users

so when you try to access rooms[i].users[k] you get a segmentation fault.

as a side note: DON'T EVER USE GLOBALS, or you'll do stupid stuff (even more when you're using globals that have the same name as members of your structs). Also, always initialize your iteration variables in first part of for loops. (Do you know people died for less than that ? :P)

here is an example of what shall be your main function:

int main() {
    room* rooms;
    user* users;

    initUsersArray(users);
    initRoomsArray(rooms);

    char *username = "Max";
    addToUsersArray(users,username);
    username = "Ma1x";
    addToUsersArray(users,username);
    printf("%s\n",users[0].username);
    printf("%s\n",users[1].username);

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(4444);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    char *room = "sportchat";
    addToRoomsArray(rooms,room);

    /* ... */

    return 1;
}

Upvotes: 2

Related Questions