Reputation: 27
I am having a bit of trouble with a test program I am working with. If I attempt to dereference a pointer in an effort to update its value causes a segfault.
This is the called function:
// Extracts a message from the community mailbox
void mbox_withdraw(struct mbox *mb, char *msg, int *len)
{
// Locks the semaphore
sem_wait(lock);
// If message node is null, there is no message, just return
if (mb->msg != NULL)
{
int var = strlen((mb->msg)->message);
len = &var;
strncpy(msg, (mb->msg)->message, len + 1);
// If there is only one message node
if ((mb->msg)->next == NULL)
{
(mb->msg)->message = NULL;
free((mb->msg)->message);
mb->msg = NULL;
free(mb->msg);
}
// There are more than one message, just take the first one
else
{
struct messageNode *temp = mb->msg;
mb->msg = (mb->msg)->next;
temp->message = NULL;
free(temp->message);
temp->next = NULL;
free(temp);
}
}
// Unlocks the semaphore
sem_signal(lock);
}
This is the calling function:
int main(void) {
t_init();
mbox_create(&mb);
t_create(producer, 1, 1);
t_create(producer, 2, 1);
t_create(consumer, 3, 1);
t_yield();
int len;
char mesg[1024];
mbox_withdraw(mb, mesg, &len); // should print a warning about the mailbox not having any messages
mbox_destroy(&mb);
t_shutdown();
printf("Done with mailbox test...\n");
fflush(stdout);
return 0;
}
If I use :
int var = strlen((mb->msg)->message);
len = &var;
No segfault but of course that is not the proper way to update the value. If I use:
int var = strlen((mb->msg)->message);
*len = var;
This is my first post on this site so please excuse me if this post seems awkward.
Upvotes: 0
Views: 69
Reputation: 46
In the function, len is a pointer. What you are doing here:
int var = strlen((mb->msg)->message);
len = &var;
strncpy(msg, (mb->msg)->message, len + 1);
is assigning the address of var to the len pointer (for example, it can be 0x12345678) and then, using the pointer (which contains 0x12345678) as a value (trying to copy 0x12345678+1 data from (mb->msg)->message to msg), causing the segfault.
The second way is the right, assigning the var value to the len pointer value (not addresses), but then you must do:
strncpy(msg, (mb->msg)->message, *len + 1);
to get the value of the pointer.
Upvotes: 1
Reputation: 3776
I think the segfault is not produced by the line you specified. If you use gcc
it's a good idea to debug either with gdb
or run in with a memory emulation like valgrind
. Then you will see which line is segfaulting.
If len
is not set properly, it will have consequences. I suppose you removed some lines but with the stated example len
don't make sense, as it is only used one time and here you can write:
strncpy(msg, (mb->msg)->message, var + 1);
Upvotes: 0
Reputation: 2335
Not compiled tested, but using my phone only. I react more on the strncpy call under. If using gcc with -Wall flag should give a warning
len = &var;
strncpy(msg, (mb->msg)->message, len + 1);
Into
*len = var;
strncpy(msg, (mb->msg)->message, *len + 1);
Or
*len = var;
strcpy(msg, (mb->msg)->message);
Upvotes: 1