0

Im codeing a little Ringbuffer in C, everything works, but if i check for memoryleeks, there is the following message:

It looks like , the "write_buffer" function causes the leak, but i cant figure out why.

valgrind --leak-check=full --track-origins=yes ./buf==3601== Memcheck, a memory error detector
==3601== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==3601== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==3601== Command: ./buf
==3601== 
start:0first:asecond:bfree element 0 
==3601== Invalid free() / delete / delete[] / realloc()
==3601==    at 0x402AF06: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3601==    by 0x8048711: delete_buffer(buffer*, int) (ringbuffer.cpp:38)
==3601==    by 0x8048895: main (ringbuffer.cpp:84)
==3601==  Address 0x8048985 is not stack'd, malloc'd or (recently) free'd
==3601== 
==3601== 
==3601== HEAP SUMMARY:
==3601==     in use at exit: 15 bytes in 3 blocks
==3601==   total heap usage: 6 allocs, 6 frees, 45 bytes allocated
==3601== 
==3601== 15 bytes in 3 blocks are definitely lost in loss record 1 of 1
==3601==    at 0x402BB7A: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3601==    by 0x8048684: create_buffer(buffer*, int, int) (ringbuffer.cpp:23)
==3601==    by 0x80487F9: main (ringbuffer.cpp:74)
==3601== 
==3601== LEAK SUMMARY:
==3601==    definitely lost: 15 bytes in 3 blocks
==3601==    indirectly lost: 0 bytes in 0 blocks
==3601==      possibly lost: 0 bytes in 0 blocks
==3601==    still reachable: 0 bytes in 0 blocks
==3601==         suppressed: 0 bytes in 0 blocks
==3601== 
==3601== For counts of detected and suppressed errors, rerun with: -v
==3601== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 0 from 0)

my code:

/*Ringbuffer->c*/
#include <stdlib.h>
#include <stdio.h>
struct buffer {
int size;
int start;
int pos;            // position of current free element
const char ** elements;
};

void create_buffer(buffer *buf, int buf_size, int elem_size){
int i =0;
buf->size =buf_size;
buf->start=0;
buf->pos=0;
    buf->elements = (const char**) malloc(buf_size*sizeof(const char *));
    if(buf->elements == NULL)
        {
        printf("out of memory\n");
        }
    for(i = 0; i < buf_size; i++)
        {
        buf->elements[i] = (const char*) malloc(elem_size * sizeof(const char));
        printf("malloc element %i \n",i);
        if(buf->elements[i] == NULL)
            {
            printf("out of memory\n");
            }
        }

}
void delete_buffer(buffer *buf,int buf_size)
{
int i=0;

   for(i=0;i<buf_size;i++)
   {
    printf("free element %i \n",i);
    free((void*)buf->elements[i]);
   }

free((void*)buf->elements);

}
void write_buffer(buffer *buf,const char* element){
    buf->elements[(buf->start+buf->pos)]=element;
    buf->pos++;
}


const char* read_buffer(buffer *buf){

    const char* ret=buf->elements[buf->start];
    buf->start++;
    return ret;
}


int buffer_is_full(buffer *buf){
    if(buf->size==buf->pos){
            return 1;
        }
    return 0;
}

int buffer_is_empty(buffer *buf){
    if(buf->size==buf->pos){
        return 1;
    }
    return 0;
}

int main (int arc, const char **argv){
    buffer buf;


    create_buffer(&buf,5,5);

    printf("start:%i",buf.pos);

    write_buffer(&buf,"a");
    write_buffer(&buf,"b");
    write_buffer(&buf,"b");
    printf("first:%s",read_buffer(&buf));
    printf("second:%s",read_buffer(&buf));

    delete_buffer(&buf,5);

}
6
  • 1
    Please don't cast the return value of malloc() in C. Also, it can't ever be const or you wouldn't need the malloc(). The const type of elements doesn't make sense. Commented Feb 7, 2014 at 13:54
  • Avoid pointers - use std::containers or std::shared/unique_ptr Commented Feb 7, 2014 at 13:55
  • @fritzone, indeed it is! Commented Feb 7, 2014 at 13:56
  • 1
    @Dieter Lücking There are no std::containers or std::shared/unique_ptr in C Commented Feb 7, 2014 at 13:59
  • @TNA Thanks (and no thanks) - I ran into this from a C++ tag Commented Feb 7, 2014 at 14:11

1 Answer 1

1

You are trying to free a const value. write_buffer(&buf,"a"); puts a const in the buffer. You cannot free that!

Sign up to request clarification or add additional context in comments.

1 Comment

Although "a" is constant (as being a literal), the const modifier does not make the program choke. However 1+ for pointing out the root cause to the issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.