Edw4rd
Edw4rd

Reputation: 147

My struct is overlapping some data from the previous one (Edit)

Hi guys I'm having a problem with pointers and memory this is my data structure:

struct user_node {
    char *name;
    struct user_node *next;
    struct msg_node *msgnext;
};

struct msg_node {
    char *sender;
    char *receiver;
    char *title;
    char *content;
    struct msg_node *msgnext;
};

I already have the user creation / deletion implemented but I'm having trouble implementing new msg, I'm using this functions:

struct msg_node* sendForm(char** res) { // Format msg before sending

    struct msg_node *temp = (struct msg_node*) malloc(sizeof(struct msg_node));

    char *aux = malloc(sizeof(char) * 400);
    int i;

    temp->sender = res[1];
    temp->receiver = res[2];
    temp->title = res[3];

    for (i = 4; i < (n_spaces + 1); i++) {
        if (res[i] != NULL) {
            strcat(aux, res[i]);
            strcat(aux, " ");
        }
    }

    temp->content = aux;
    return temp;
}

int sendMsg(struct msg_node* msg)
{
    struct user_node* user = user_database;

    if (user == NULL) {
        printf("There aren't users on the system.\n");
        return -1;
    }

    while (user != NULL) {
        if (strncmp(user->name, msg->receiver, strlen(msg->receiver)) == 0) {
            msg->msgnext = user->msgnext;
            user->msgnext = msg;
            readmsglist();
            return 0;
        }

        user = user->next;
    }

    printf("User '%s' not found on the system.\n", msg->receiver);

    return -1;
}

This is actually working if I only input one msg but when I try to implement the second one this is what's happening:

Execution:

Welcome to the Program> Enter command (h for help):register user
User created

There are 1 users right now 

> Enter command (h for help):send RandomUser1 user content1 a b c
Receiver -> user
Sender -> RandomUser1
Subject ->  content1
Content:
 a b c

> Enter command (h for help):send RandomUser2 user content2 d e f
Receiver -> user
Sender -> RandomUser2
Subject ->  content2
Content:
 d e f

Receiver -> user
Sender -> RandomUser2
Subject ->  content2
Content:
 a b c

and so more...

The weirdest part here is that the content is never overlaped but the other parts actually are.

Btw Sorry for my previous post that had to much code.

Edit: (Data output function)

void readmsglist() { // Show the msg of the first user Test Purposes
    struct msg_node** ptr = &user_database->msgnext;

    while (*ptr) {
        printf("Receiver -> %s\n", (*ptr)->receiver);
                printf("Sender -> %s\n", (*ptr)->sender);
                printf("Subject ->  %s\n", (*ptr)->title);
                printf("Content:\n %s\n", (*ptr)->content);
                ptr = &(*ptr)->msgnext;
    }

}

Edit2 (More info):

First, the function is called here:

case 24: //Send messages
            if (countSpaces(input) > 2) {
                sendMsg(sendForm(cut(input)));

            } else {
                E_Type();
            }
            break;

This is the cut function:

    char** cut(char str[]) {

    char ** res = NULL;
    char * p = strtok(str, " ");
    n_spaces = 0; // Global variable (int)

    /* split string and append tokens to 'res' */

    while (p) {
        res = realloc(res, sizeof(char*) * ++n_spaces);

        if (res == NULL)
            exit(-1); /* memory allocation failed */

        res[n_spaces - 1] = p;

        p = strtok(NULL, " ");
    }

    /* realloc one extra element for the last NULL */

    res = realloc(res, sizeof(char*) * (n_spaces + 1));
    res[n_spaces] = 0;

    return res;
}

The input is like -> send :

Upvotes: 1

Views: 333

Answers (1)

jwdonahue
jwdonahue

Reputation: 6669

Edw4d and I had a long discussion and debugging session.

The message data is being overwritten by user input because the location of the data in input buffer in each message is being stored in each message node, rather than actually copying the string into a new buffer. This solves the problem:

char** cut(char str[])
{
    char *p = strtok(str, " "); // We don't need the first token.
    p = strtok(NULL, " ");

    char **res = calloc(sizeof(char*), 4); /* allocate a buffer full of NULL's*/
    if (res == NULL) exit(-1); /* memory allocation failed */

    /* split string and append tokens to 'res' */
    for (int idx = 0; idx < 3; idx++)
    {
        res[idx] = malloc(strlen(p) + 1);
        strcpy(res[idx], p);
        p = strtok(NULL, " ");
    }

    p[strlen(p)] = ' '; // Put the space back where strtok wrote the null character.
    res[3] = malloc(strlen(p) + 1);
    strcpy(res[3], p);
    return res;
}

MsgNode* sendForm(char** res) { // Format msg before sending

    struct msg_node *temp = (struct msg_node*) malloc(sizeof(struct msg_node));

    temp->receiver = res[0];
    temp->sender = res[1];
    temp->title = res[2];
    temp->content = res[3];

    return temp;
}

Upvotes: 1

Related Questions