0

I have a very simple implementation of a buffer with writing and reading index in C. Below is the .c file and then after the main().

Cant see why but I'm getting the Segmentation fault (core dumped).

The .c file is below.

    #include <stdio.h>
#include <stdlib.h>
#include "contbuf.h"

typedef struct cont_buf
{
    char *buf;
    ln_bsize size;
    int read_index;
    int write_index;
    int has_data;
} cont_buf;

cont_buf *create_cont_buf(ln_bsize *size)
{
    cont_buf *cb;
    cb->buf = malloc(sizeof(float)*(*size));
    if(cb->buf == NULL){
        printf("Failed to get or allocate memory\n");
        exit(1);
        }
    cb->size = *size;
    cb->read_index = 0;
    cb->write_index = 0;
    cb->has_data = 0;

    if (!cb->buf)
        return NULL;

    return cb;
}

void free_cont_buf(cont_buf *cb)
{
    free(&cb->buf);
}

void write_float_to_cb(cont_buf *cb, float *f)
{
    if ((cb->write_index + 1) > cb->size)
    {
        cb->write_index = 0;
    }

    cb->buf[cb->write_index] = *f;
    cb->write_index += 1;

    if (cb->write_index > cb->has_data)
        cb->has_data = cb->write_index;
}

void read_float_from_cb(cont_buf *cb)
{
    float f;
    f = cb->buf[cb->read_index];
    printf("float number: %f\n", f);
}

And here is the main() file, just to teste the functions in the C.

There is also a .h file that I'm not sharing but it is just declaration of the functions and typedefs.

#include <stdio.h>
#include <stdlib.h>
#include "contbuf.h"

    int main() {
    
        struct cont_buf* cb;
        ln_bsize* size;
        *size = (ln_bsize)20;
        float *f;
        *f = 3.25F;
    
        cb = create_cont_buf(size);
    
        write_float_to_cb(cb, f);
    
        read_float_from_cb(cb);
    
        return 0;
    
    }

Could someone help me to figure out why ? I also don't find a way to troubleshoot since the run doesn't even run, so I cannot tell when the code breaks.

Rodrigo Belli
  • 774
  • 1
  • 7
  • 11

3 Answers3

1

You have a primary issue in

    ln_bsize* size;
    *size = (ln_bsize)20;

here, size does not point to any valid memory location, yet to you try to dereference it and put value into the memory location pointed by it. This is invalid memory access which invokes undefined behaviour.

To avoid this, you need to ensure that size points to valid memory location. For this case, you can avoid the problem by not making size a pointer type altogether. Just do

 ln_bsize size = 20;

and then, pass it to the function like

  cb = create_cont_buf(&size);

You have the problem of using /dereferencing uninitiated memory in many other places of the code.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0
 cont_buf *cb;
 cb->buf = malloc(sizeof(float)*(*size));

cb is not initialized but you dereference it, the behavior is undefined

   ln_bsize* size;
   *size = (ln_bsize)20;

same thing about size

I encourage you to take into account the warnings produced by the compiler, and to ask for the more possible using option like -Wall or better -Wall -Werror if using gcc

bruno
  • 32,421
  • 7
  • 25
  • 37
0

Your forgot to allocate memory for where cont_buf *cb and ln_bsize* size should point to.

cb and size are just pointers. Their intent is to point to objects of the respective types.

The attempt to initialize any members of a structure like at cb->buf = malloc(sizeof(float)*(*size)); or to initialize the referenced object *size = (ln_bsize)20; invokes undefined behavior.

Allocate memory for where they should point to:

cont_buf *cb = malloc(sizeof(cont_buf));
if (!cb)
{
    fputs("Error at allocation!", stderr);
    return EXIT_FAILURE;
}

and

ln_bsize* size = malloc(sizeof(ln_bsize));
if (!size)
{
    fputs("Error at allocation!", stderr);
    return EXIT_FAILURE;
}
  • What if I want to malloc the "char *buf" dynamically (according to the function parameter size) ? but no the full struct ? – Rodrigo Belli Jul 09 '20 at 23:41