Pointers and Structs in C

  • Thread starter frankfjf
  • Start date
  • Tags
    Pointers
  • #1
168
0
Hello all,

I am experiencing some odd output behavior from a program that I am working on:

Header file

Code:
#include <pthread.h>

struct ringbuf_t
{
  pthread_mutex_t mutex;
  pthread_cond_t cond_full;
  pthread_cond_t cond_empty;
  int bufsiz;
  int front;
  int back;
  char* buf;
};

extern struct ringbuf_t* rb_init (int bufsiz);

extern void rb_finalize (struct ringbuf_t* rb);

extern int rb_size (struct ringbuf_t* rb);

extern int rb_is_full (struct ringbuf_t* rb);

extern int rb_is_empty (struct ringbuf_t* rb);

extern void rb_insert (struct ringbuf_t* rb, int c);

extern int rb_remove (struct ringbuf_t* rb);

First source file

Code:
#include "ringbuf.h"
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>

struct ringbuf_t* rb_init(int bufsiz)
{
  int x;
  char *temp = malloc(sizeof(char) * bufsiz);
  memset(temp, '\0', sizeof(temp));

  //temp[bufsiz-2] = 'w';

  struct ringbuf_t newrb = { PTHREAD_MUTEX_INITIALIZER,
			     PTHREAD_COND_INITIALIZER,
			     PTHREAD_COND_INITIALIZER,
			     bufsiz, 0, bufsiz - 1, temp };

  struct ringbuf_t* p = malloc(sizeof(struct ringbuf_t));
  p = &newrb;

  return p;
}

void rb_finalize(struct ringbuf_t* rb)
{
  free(rb);
}

int rb_size(struct ringbuf_t* rb)
{
  int x;
  
  for (x = 0; rb->buf[x] != '\0'; x++)
    ;

  return x;
}

int rb_is_full(struct ringbuf_t* rb)
{
  if (rb->buf[rb->back] != '\0')
    return 1;

  return 0;
}

int rb_is_empty(struct ringbuf_t* rb)
{
  if (rb->buf[rb->front] != '\0')
    return 0;

  return 1;
}

Main source file
Code:
#include <stdio.h>
#include <stdlib.h>
#include "ringbuf.h"

int main()
{
  printf("\nTesting first method...");
  struct ringbuf_t *p = malloc(sizeof(struct ringbuf_t));
  p = rb_init(10);

  printf("\n%d", p->bufsiz);
  printf("\n%d", p->bufsiz);

  return 0;
}

I have been using the main method to test stuff out, and currently am experiencing some odd behavior, which I think may have to do with how I am allocating memory or using pointers, I am not sure. Basically, the first time I reference anything within the created struct (in this test I referenced bufsiz), it reports the correct value the first time, and then gives junk every time afterward. Same thing for function calls or a combination of both, as if the data is only available initially and then is immediately lost as soon as it gets accessed once.

Is there something off in my code that is causing this?

Thank you in advance.
 

Answers and Replies

  • #2
In main, you allocate a block of memory for a ring buffer, and then call rb_init, which also allocates a block of memory. You shouldn't need to do this twice.
 
  • #3
Fair enough, but even implementing that fix causes the problem to persist.
 
  • #4
Try:
*p = newrb;
instead of
p = &newrb;

That is, you need to copy the contents that is pointed to, and not the pointer itself.
 
  • #5
Ooh, I think that fixed it! Thank you so much. Now hopefully I can actually get to the multi-threading part and actually get to the intended practice. :P
 
  • #6
Just so you know, you should also use:
memset(temp, '\0', sizeof(char) * bufsiz);

instead of:
memset(temp, '\0', sizeof(temp));

Otherwise, you only set the first 4 bytes (which is the size of a pointer) of your buffer to zero .
 
  • #7
Will do. Thanks. Playing around with pointers and memory seems to be my stumbling block in C.
 
  • #8
Try:
*p = newrb;
instead of
p = &newrb;

That is, you need to copy the contents that is pointed to, and not the pointer itself.
In case it's not obvious why p = &newrb; isn't working for you, here's an explanation.

In main, p is set to the address of a ring buffer struct whose memory has been allocated from the heap. All is good.

In rb_init, a local variable named newrb is created. This struct is allocated on the stack. Just before rb_init exits, p is set to the address of newrb. Note that stack variables cease to exist outside the function in which they are declared. In practical terms, this means that whatever was at that location during the function's life can be used for other purposes after the function exits.

Back in main, p is pointing to a location on the stack that no longer holds what was stored in newrb.
 
  • #9
Ah-ha. I figured it was something like that based on the behavior. Thank you Mark.
 

Suggested for: Pointers and Structs in C

Replies
3
Views
247
Replies
17
Views
798
Replies
7
Views
1K
Replies
2
Views
1K
Replies
15
Views
492
Replies
2
Views
234
Replies
3
Views
226
Replies
8
Views
2K
Replies
3
Views
2K
Replies
2
Views
956
Back
Top