Reputation: 17
I'm trying to implement a basic circular buffer and then produce/consume several characters within said buffer. Since multiple threads will be accessing the same buffer, I'm also using semaphores to prevent concurrent accesses. My program compiles and runs correctly, but, once I pass it a character, it leads to a segmentation fault. I've been trying to debug using Valgrind, but I haven't been able to glean much of use from it aside from the fact that the error lies in my buffer code, which is below:
[...]//headers
void createBuffer(Buffer *buff, int buffSize){
buff = (Buffer*) calloc(1, sizeof(Buffer));
semaphore mutex,emptyBuffers,fullBuffers;
createSem(&mutex, 1);
createSem(&emptyBuffers,buffSize);
createSem(&fullBuffers,0);
(buff->mutex) = &mutex;
(buff->emptyBuffers) = &emptyBuffers;
(buff->fullBuffers) = &fullBuffers;
buff->charBuff = malloc(sizeof(char) * buffSize);
buff->nextIn = 0;
buff->nextOut = 0;
buff->buffSize = buffSize;
}
void deposit(char in, Buffer *buffer) {
down(buffer->emptyBuffers); //line 20 in buffer.c
(buffer->charBuff)[buffer->nextIn] = in;
buffer->nextIn = (buffer->nextIn + 1) % buffer->buffSize;
up(buffer->fullBuffers);
}
[...]//remove function
The remove function afterwards is analogous to deposit(), so figuring out how to fix one should be enough for me to figure out how to fix the other if necessary. Here's the Valgrind output:
==10846== Use of uninitialised value of size 8
==10846== at 0x4014EF: deposit (buffer.c:20)
==10846== by 0x40124F: getInputStream (test.c:80)
==10846== by 0x401C55: _st_thread_main (in a.out)
==10846== by 0x401D1D: st_thread_create (in a.out)
==10846==
==10846== Invalid read of size 4
==10846== at 0x40167A: down (in a.out)
==10846== by 0x4014FA: deposit (buffer.c:20)
==10846== by 0x40124F: getInputStream (test.c:80)
==10846== by 0x401C55: _st_thread_main (in a.out)
==10846== by 0x401D1D: st_thread_create (in a.out)
==10846== Address 0xc74800405020c0c7 is not stack'd, malloc'd or (recently) free'd
==10846==
==10846== Process terminating with default action of signal 11 (SIGSEGV)
==10846== General Protection Fault
==10846== at 0x40167A: down (in a.out)
==10846== by 0x4014FA: deposit (buffer.c:20)
==10846== by 0x40124F: getInputStream (test.c:80)
==10846== by 0x401C55: _st_thread_main (in a.out)
==10846== by 0x401D1D: st_thread_create (in a.out)
I'm quite new to Valgrind (and only a novice with C), so I've been searching for others with similar Valgrind outputs, but I haven't been able to find anything that's helped.
A couple final notes (apologies for this being so long!): this is for school, so I would prefer guidance over code if possible. Also, though the Valgrind output does mention a connection between the "invalid read" and the down function, I can confirm that the down function--and the semaphore type itself--operates properly on its own. Finally, I did have some difficulties initializing the buffer and allocating memory in createBuffer(); combined with the nature of seg faults, I wouldn't be surprised if the error had something to do with that function, though Valgrind doesn't reference it.
TL;DR: Seg fault in program that, as someone new to Valgrind and fairly inexperienced with C, I've had trouble understanding. Code above. Thanks!
EDIT: After realizing my error as a result of the helpful advice given below, I've since run into another seg fault when trying to allocate memory to my semaphores to prevent their loss. I've tried several methods, each with the same result. My new attempts are below:
buff->mutex = calloc(1,sizeof(semaphore));
buff->mutex = &mutex;
and
buff->mutex = calloc(1,sizeof(semaphore));
createSem(buff->mutex,1);
//I removed the previous semaphore declarations and calls to createSem(...)
As with my first problem, these still lead to a segmentation fault when the semaphore is first referenced outside of createBuffer(...).
Upvotes: 0
Views: 592
Reputation: 409442
You are using pointers to local variables. Once a function returns, the space once used by those variables is reclaimed and reused for the next function call.
Remember that the lifetime of a local variable is only in the function the variable is defined.
Upvotes: 1