Search code examples
cmemoryirc

Char[] Losing Data


So I have a structure that stores info about IRC connection. It works fine but when I try to modify the value it goes empty;

Here is my structure:

struct connection_info{
    char user[MAXBUFF + 1];
    char host[MAXBUFF + 1];
    char port[MAXBUFF + 1];
    char nick[MAXBUFF + 1];
    char channel[MAXBUFF + 1];
};

struct connection_info info; //Global Struct

Then I have a global structure (connection_info) and my main method that defines each element in the structure and connects to an IRC server. After I connect to an IRC server I listen for messages and parse them. After I do that I respond to each message differently. Here is where my problem occurs.

 if(strstr(message.message, "!JOINCHANNEL") != NULL){
        char* str = strtok(message.message, " ");
        char* channel = strtok(NULL, " ");

        if(str == NULL || channel == NULL || (*channel) != '#'){
            strcpy(buff, "PRIVMSG ");
            strcat(buff, info.channel);
            strcat(buff, " :Please use format !JOINCHANNEL [#CHANNEL]\r\n");
            while(send_message(buff) == -1);
        }else{
            strcpy(buff, "PART ");
            strcat(buff, info.channel);
            strcat(buff, "\r\n");
            while(send_message(buff) == -1);

            memeset(info.channel, 0, sizeof(info.channel));
            strcpy(info.channel, channel);

            memset(buff, 0, sizeof(buff));
            strcpy(buff, "JOIN ");
            strcat(buff, info.channel);
            strcat(buff, "\r\n");
            while(send_message(buff) == -1);
        }
    }

Two Questions:

It actually changes to the correct channel unless I get weird characters in the channel name which I sometimes do (upside down question mark). Why does this sometimes happen and it never happens if my message.message is three parts "!JOINCHANNEL #test random" but when it has two parts it sometimes gives me random characters: "!JOINCHANNEL #test". How can I fix this?

Second and more importantly, after the handle_message function returns, the value of info.channel seems to disappear. I thought strcpy() would work to retain value after return because it is a char[4097] but it doesn't seem to. Am I doing something wrong or is there an error I haven't heard of.


Solution

  • EDIT: Assuming buff already is a malloc'd pointer (since you are passing it into a function and as far as I know there aren't any functionality issues there), I've modified my code. I misunderstood it when I first answered this question.

    I don't see any dynamic memory allocation and char[4097] does not do that so I feel like that's the problem. I'll delete this answer if that's not it.

    Basically after the function returns, the memory allocated on the stack in char[4097] falls out of scope. You need the memory to persist regardless of what the stack looks like. You want to include code that looks like this outside handle_message:

    struct connection_info{
        char* user;
        char* host;
        char* port;
        char* nick;
        char* channel;
    };
    
    struct connection_info* info
    

    and in handle_message:

    info = malloc(sizeof(connection_info));
    // Then, in the code snippet you posted
    if(strstr(message.message, "!JOINCHANNEL") != NULL){
        //You can initialize with calloc instead of memset with 0s
        info->channel = calloc(strlen(channel)+1); 
        strcpy(info->channel, channel);
    }