stak0verflow
stak0verflow

Reputation: 27

Segfault updating an int pointer in c

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

Answers (3)

O Moya
O Moya

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

Günther Jena
Günther Jena

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

Stian Skjelstad
Stian Skjelstad

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

Related Questions