0
#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

6
  • 1
    C++ happens to be so much clearer in programs like these... You probably forgot to initialize some field. Too bad that you're using unix, Visual Studio would break you at the variable that's uninitialized. Commented May 19, 2012 at 16:14
  • first of all, avoid globals as much as you can ! in "if(rooms[i].users[k].username=='\0')" rooms[i].users is a null pointer, so missed some initialization somewhere, but your code is quite messy. Commented May 19, 2012 at 16:15
  • You should use strcmp class of function to compare C strings & not == Commented May 19, 2012 at 16:18
  • Do i may need to allocate mem for rooms[i].users? Should i compile with -Wall -Wextra. I am new to c and gcc. Commented May 19, 2012 at 16:24
  • 1
    users[i].username=='\0' does not what you probably think it does. username is a char* that is a pointer to a character array. You compare that pointer to the integer '\0'. By coincidence this integer is just the value 0 and so you actually test if username is set to something or not. But I guess that this is pure coincidence. Commented May 19, 2012 at 16:35

2 Answers 2

2

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;
}
Sign up to request clarification or add additional context in comments.

4 Comments

I am new to c. Why does using globals is so bad?
because you can not follow the life of each variable in your code. Usually, you declare your variable in your main() function, and then pass them to every function. see my next edit.
so that way, you have your rooms and users variables, and you can correctly follow their lifes, and have multiple instances of them. And you'll find out more easily where in your code you should have put the missing allocation/initialization of room.users
you can use realloc each time you add/remove a user from a room, but that will enforce a full copy of all the memory already allocated, and thus be a real performance drop. You shall better implement your room as a linked list of users, so you can easily remove or add users in your list : exforsys.com/tutorials/c-language/c-linked-lists.html and as it really looks like a homework, I'm only giving you tips to make your code better, but I won't write it for you.
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.