multithreading - Double Buffer presenting memory leaks [ANSI C] -
i doing library implement double buffer, basic idea there have buffers, 1 written , other read , swap every time write buffer gets full. having memory leaks time when swapping buffers , getting valgrind:
==4778== thread 2: ==4778== invalid read of size 1 ==4778== @ 0x804a302: swapbuffer (doublebuffer.c:85) ==4778== 0x804a1fa: setdoublebuffer (doublebuffer.c:39) ==4778== 0x804935c: tempcontrol (t2.c:167) ==4778== 0x4062f6f: start_thread (pthread_create.c:312) ==4778== 0x4163bed: clone (clone.s:129) ==4778== address 0x4228098 0 bytes after block of size 4,000 alloc'd ==4778== @ 0x402c109: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==4778== 0x804a0ff: build_double_buffer (doublebuffer.c:14) ==4778== 0x8048e49: init (t2.c:56) ==4778== 0x804988a: main (t2.c:299) ==4778== ==4778== invalid read of size 1 ==4778== @ 0x804a2e8: swapbuffer (doublebuffer.c:86) ==4778== 0x804a1fa: setdoublebuffer (doublebuffer.c:39) ==4778== 0x804935c: tempcontrol (t2.c:167) ==4778== 0x4062f6f: start_thread (pthread_create.c:312) ==4778== 0x4163bed: clone (clone.s:129) ==4778== address 0x4228098 0 bytes after block of size 4,000 alloc'd ==4778== @ 0x402c109: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==4778== 0x804a0ff: build_double_buffer (doublebuffer.c:14) ==4778== 0x8048e49: init (t2.c:56) ==4778== 0x804988a: main (t2.c:299) ==4778== ==4778== invalid write of size 1 ==4778== @ 0x804a2eb: swapbuffer (doublebuffer.c:86) ==4778== 0x804a1fa: setdoublebuffer (doublebuffer.c:39) ==4778== 0x804935c: tempcontrol (t2.c:167) ==4778== 0x4062f6f: start_thread (pthread_create.c:312) ==4778== 0x4163bed: clone (clone.s:129) ==4778== address 0x4229068 0 bytes after block of size 4,000 alloc'd ==4778== @ 0x402c109: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==4778== 0x804a11a: build_double_buffer (doublebuffer.c:15) ==4778== 0x8048e49: init (t2.c:56) ==4778== 0x804988a: main (t2.c:299) i've been trying make work, can't see doing memory leak not how fix it. code below:
#include<stdlib.h> #include<stdio.h> #include<string.h> #include<pthread.h> #include"data_structures.h" #define buffer_size 4000 typedef enum {firstbuf, secondbuf} currentbuf; typedef struct { char *buffer1; char *buffer2; currentbuf current; int index; } double_buffer; pthread_cond_t buffer_cheio = pthread_cond_initializer; pthread_cond_t buffer_vazio = pthread_cond_initializer; pthread_mutex_t mutex; double_buffer *build_double_buffer(){ double_buffer *db = (double_buffer *)malloc(sizeof(double_buffer)); db->buffer1 = (char *)calloc(buffer_size, sizeof(char)); db->buffer2 = (char *)calloc(buffer_size, sizeof(char)); db->buffer1[0] = '\0'; db->buffer2[0] = '\0'; db->index = 0; pthread_mutex_init(&mutex, null); db->current = firstbuf; return db; } void setdoublebuffer(double_buffer *db, char *info){ pthread_mutex_lock(&mutex); int len = strlen(info)+1; if(db->index + len > buffer_size){ switch(db->current){ case firstbuf: while(db->buffer2[0] != '\0'){ pthread_cond_wait(&buffer_vazio, &mutex); } break; case secondbuf: while(db->buffer1[0] != '\0'){ pthread_cond_wait(&buffer_vazio, &mutex); } } swapbuffer(db); } if(db->current == firstbuf){ if(!(db->index + len > buffer_size)){ strcat(db->buffer1, info); }else{ printf("erro"); } }else{ if(!(db->index + len > buffer_size)){ strcat(db->buffer2, info); }else{ printf("erro"); } } db->index += len; pthread_cond_signal(&buffer_cheio); pthread_mutex_unlock(&mutex); } void swapbuffer(double_buffer *db){ int i; char *buf1; char *buf2; if(db->current == firstbuf) { buf1 = db->buffer1; buf2 = db->buffer2; } else { buf2 = db->buffer1; buf1 = db->buffer2; } for(i = 0; < buffer_size -1 || buf1[i] == '\0'; i++){ //line 85 buf2[i] = buf1[i]; //line 86 } buf1[0] ='\0'; db->index = 0; if(db->current == firstbuf){ db->current = secondbuf; }else{ db->current = firstbuf; } } void get_buffer(char *receivebuffer, double_buffer *db){ pthread_mutex_lock(&mutex); int i; while(db->buffer1[0] == '\0' || db->buffer2[0] == '\0'){ pthread_cond_wait(&buffer_cheio, &mutex); } if(db->current == firstbuf){ for(i = 0; < buffer_size || db->buffer2[i] == '\0'; i++){ receivebuffer[i] = db->buffer2[i]; } db->buffer2[0] = '\0'; }else{ for(i = 0; < buffer_size || db->buffer1[i] == '\0'; i++){ receivebuffer[i] = db->buffer1[i]; } db->buffer1[0] = '\0'; } pthread_cond_signal(&buffer_vazio); pthread_mutex_unlock(&mutex); } the code calls is:
//main thread before creating threads log_buffer = build_double_buffer(); //temparature thread while(1){ char *log_string = null; log_string = (char *)malloc(sizeof(char)*max_buffer_size); //code calculates t sprintf(log_string, "temperura: %f\n", t); setdoublebuffer(log_buffer, log_string); }
Comments
Post a Comment