0

I am having some problems when returning with printf of a char array from a struct in C.

struct q_entry
{
    long mtype;
    char mtext[MAXLENGTH + 1];
};

The long mtype from the struct is returning fine, but the string is just returning some weird characters.

int proc_obj(struct q_entry *msg)
{
    printf("\npriority: %ld name: %s\n", msg->mtype, msg->mtext);
}

It just returns some strange characters like "priority: 1 name: ▒▒(" and not "priority: 1 name: hello"

I am populating the struct using the following code

int enter(char *objname, int priority)
{
    ...

    strncpy(s_entry.mtext, objname, sizeof(s_entry.mtext) - 1);
    s_entry.mtype = priority;

    // Send the message
    if (msgsnd(s_qid, &s_entry, len, 0) == -1)
    {
        printf("error: msgsnd failed\n");
        return(-1);
    }
    else
    {
        return(0);
    }
}

I don't have much experience with C, so I don't know too much about using structs. Please let me know if more context or parts of the code is needed. Any kind of help would be very helpful.

I have added a little more code in enter above, and here is more code of the when enter and proc_obj are called

main(int argc, char **argv)
{
    int priority;

    if (argc != 3)
    {
        printf("error: incorrect number of arguments\n");
        exit(1);
    }
    else
    {
        priority = atoi(argv[2]);
    }

    if (enter(argv[1], priority) < 0)
    {
        printf("error: message entering failed\n");
        exit(1);
    }

    exit(0);
}

This is in a different file from enter and above code

int server(void)
{
    int mlen, r_qid;
    struct q_entry r_entry;

    // Initialize queue
    if ((r_qid = init_queue()) == -1)
        return(-1);

    for (;;)
    {
        if ((mlen = msgrcv(r_qid, &r_entry, MAXLENGTH, (-1 * MAXPRIOR), MSG_NOERROR)) == -1)
        {
            printf("error: msgrcv failed\n");
            exit(1);
        }
        else
        {
            proc_obj(&r_entry);
        }
    }
}
4
  • 3
    you'll need to show the code where your enter() method is called Commented Aug 7, 2011 at 1:00
  • 3
    In fact, it would be helpful to show us a small, complete, compilable program that demonstrates the problem. Commented Aug 7, 2011 at 1:13
  • So, I checked mlen, and it was 0. The return value of msgrcv "returns the number of bytes actually copied into the mtext array." So, I think that there is something wrong when I populate the struct. I am not sure, but is the value of the string not being passed and is being referenced, and when the server method tries to get the message from queue it is no longer able to reference the string? Commented Aug 7, 2011 at 2:41
  • Thanks for the suggestion phoxis. Checking the size of len helped me figure out what was the problem. Commented Aug 7, 2011 at 5:16

3 Answers 3

2

The only obvious error in your code is that you should explicitly fill in a zero at s_entry.mtext[MAXLENGTH] such that the string will still be zero terminated if strncpy() hits the limit. But if that were the problem, you would see "hello" followed by strange characters. Are you sure that objname points to the text you're expecting it to point to?

Also, it looks a bit strange that proc_obj() is declared to return an int but actually does not return anything. Your compiler ought to complain about that.

Sign up to request clarification or add additional context in comments.

3 Comments

Perhaps there's a return statement in the trailing "...".
@Keith Thompson proc_obj() doesn't have a trailing "..."; enter() does.
I have tried to fill in a zero at s_entry.mtext[MAXLENGTH] after seeing other posts, but it doesn't seem to make a difference. When I try to just return objname it does show the correct text. Would using msgsnd and msgrcv to send the message to a message queue and receive the message affect the output?
1

Answer before adding more code

It looks like the s_entry structure object is local, and enter works on the local variable. How are you calling enter and returning the structure after you have done initializing it ? note that you have int as the return type of the enter function. If you are doing return s_entry; then the output you are getting is possible, as only the first word of the structure, ie the lower sizeof (int) part of mtype is considered.

If you are using enter function like this as i described above then make the return type of enter to struct s_entry


You should check the size of len when sending the message.

5 Comments

The struct s_entry is being sent to a message queue after being populate using the following code code if (msgsnd(s_qid, &s_entry, len, 0) == -1) { printf("error: msgsnd failed\n"); return(-1); } code and then it is being received using code for (;;) { if ((mlen = msgrcv(r_qid, &r_entry, MAXLENGTH, (-1 * MAXPRIOR), MSG_NOERROR)) == -1) { printf("error: msgrcv failed\n"); exit(1); } else { proc_obj(&r_entry); } } code
you need to show us the enter call and the proc_obj call and where you have called proc_obj .
enter does not actually call proc_obj, it only sends the message to a message queue, and then another program called server retrieves the message and calls proc_obj
the high level details is nor required. We need to know the call line of the enter and the proc_obj , these can give us vital information. Please update the question with some more code.
can we get the message send function call line in the client ?
0

You don't show the message queue call but my guess is you are somehow miscalling the API and putting garbage into the queue (and then printing garbage in the server).

1 Comment

I don't think this is happening, since the long mtype is returning fine. I think it could be a more simple mistake with how the char is being passed or referenced or whatever that I just can't seem to figure out.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.