How to properly use pointers and structs in C?

  • Thread starter frankfjf
  • Start date
  • Tags
    Pointers
In summary, you are experiencing some odd output behavior from a program that you are working on. It seems that you are allocating memory incorrectly, and this may be causing the problem.
  • #1
frankfjf
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.
 
Physics news on Phys.org
  • #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
I like Serena said:
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.
 

What are pointers in C and how do they work?

Pointers in C are variables that store the memory address of another variable. They are used to indirectly access and manipulate data stored in memory. Pointers work by pointing to a specific memory address, and allowing the programmer to read or modify the data at that address.

What are structs in C and how are they used?

Structs in C are user-defined data types that allow the programmer to combine different types of variables into a single data structure. They are used to group related data together and are often used to represent real-world entities. Structs can contain variables of different data types and can be accessed using the dot operator.

How are pointers and structs related in C?

Pointers and structs are related in C because pointers can be used to store the memory address of a struct. This allows for dynamic memory allocation and manipulation of structs using pointers. Pointers can also be used to access and modify individual elements within a struct.

How do you declare and initialize a pointer to a struct in C?

To declare and initialize a pointer to a struct in C, you first need to define the struct using the struct keyword. Then, you can declare a pointer variable using the * symbol before the variable name. To initialize the pointer to point to a specific struct, you can use the & operator followed by the struct variable name.

What are the potential pitfalls of using pointers and structs in C?

One potential pitfall of using pointers and structs in C is the risk of memory leaks and dangling pointers. If pointers are not properly initialized or freed after use, they can cause memory leaks which can lead to performance issues. Additionally, improper use of pointers can also result in dangling pointers, which can point to invalid or deallocated memory addresses.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
2
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
8K
  • Engineering and Comp Sci Homework Help
Replies
17
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
673
  • Engineering and Comp Sci Homework Help
Replies
3
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
5K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
929
Back
Top