Update:
Removing the print statement (line 52) entirely with all else the same as in the code below gave me 0 errors. The errors exist within my functions when printing (using philo[i]) and in this print statement (added for debugging), but do not exist if I run the entire program with no prints. Any ideas what I'm doing wrong???
Thank you for the help so far. I have made a couple of changes based on comments received so far.
***** Original (Edited) Question *****
I can't figure out why I have been getting this error, "Uninitialised value was created by a stack allocation". I started with a completed program that works fine, but gives me a ton of uninitialized value errors. I have traced the problem down to a few lines of code by excluding all functions and adding additional print statements. This code is to solve the dining philosopher's problem using threads (homework), so I don't want to post too much. My code is now:
#include <all needed header files>
#define NUM_PHIL 5
#define MIN_EAT_TIME 10
pthread_t philosopher[NUM_PHIL]; // array to hold IDs for philosopher threads
pthread_mutex_t chopstick[NUM_PHIL]; // array to hold IDs for chopstick mutexes (locks)
// function definitions here:
int philosopherFun(int *philo);
// All others have been bypassed at the time of my current problem
int main(int argc, char *argv[]) {
int phil[NUM_PHIL]; // Philosopher numbers ("names")
for(int i = 0; i < NUM_PHIL; i++) {
phil[i] = i + 1;
}
for(int i = 0; i < NUM_PHIL; i++) {
// Print statement causes valgrind error to exist (as does calling a function using phil)
printf("Value phil[%d] = %d\n", i, phil[i]);
}
// Initilize mutexes for chopsticks, report error as needed
for(int i = 0; i < NUM_PHIL; i++) {
if(pthread_mutex_init( stuff here) < 0) {
// error reporting
// print statement uses i
}
}
for(int i = 0; i < NUM_PHIL; i++) {
if(pthread_create(&philosopher[i], NULL, (void*) philosopherFun, (void*) &phil[i] ) != 0) {
// error reporting
// print statement uses phil[i]
}
}
/* Code omitted as this is Homework */
// Join threads created for philosophers (using pthread_join)
// error reporting
// print statement uses phil[i]
// Destroy chopstick mutexes when done. (using pthread_mutex_destroy)
// error reporting
// print statement uses i
printf("The philosophers have all finished eating and its time for bed. Goodnight...\n");
return 0;
}
int philosopherFun(int *philo) {
return 0;
}
Program output:
Value phil[0] = 1
Value phil[1] = 2
Value phil[2] = 3
Value phil[3] = 4
Value phil[4] = 5
The philosophers have all finished eating and its time for bed. Goodnight...
My Valgrind errors are:
==46556== HEAP SUMMARY:
==46556== in use at exit: 0 bytes in 0 blocks
==46556== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==46556==
==46556== All heap blocks were freed -- no leaks are possible
==46556==
==46556== ERROR SUMMARY: 10 errors from 1 contexts (suppressed: 0 from 0)
==46556==
==46556== 10 errors in context 1 of 1:
==46556== Conditional jump or move depends on uninitialised value(s)
==46556== at 0x7FFF205A395F: ??? (in /dev/ttys000)
==46556== by 0x7FFF2046FFFA: ??? (in /dev/ttys000)
==46556== by 0x7FFF20478CF0: ??? (in /dev/ttys000)
==46556== by 0x7FFF2049D8B8: ??? (in /dev/ttys000)
==46556== by 0x7FFF20475EF5: ??? (in /dev/ttys000)
==46556== by 0x7FFF20474061: ??? (in /dev/ttys000)
==46556== by 0x1000038CD: main (philo.c:52)
==46556== Uninitialised value was created by a stack allocation
==46556== at 0x7FFF20475FDF: ??? (in /dev/ttys000)
==46556==
==46556== ERROR SUMMARY: 10 errors from 1 contexts (suppressed: 0 from 0)
line 52 is my print statement:
printf("Value phil[%d] = %d\n", i, phil[i]);
which I believe accounts for 5 errors (phil[0] - phil[4]) and I call philosopherFun in my pthread_create on line 68 (this line of code included), again accounting for 5 errors (1 for each thread). This function is currently only returning on the first line, so none of the rest of my program is involved (though I started with 50-250 errors depending on my parameters and which functions I excluded).
I feel like my int array (int phil[]) is causing the problem, but it is immediately initialized, so I'm not sure how this is happening. Please help!
Thanks,
Kristine
Edited... Added some comments from omitted code- Threads are joined and mutexes destroyed
I also tried making int phil[NUM_PHIL] global by declaring it outside of my main function, but this made no change to the errors returned by Valgrind. defining phil[5] = {1, 2, 3, 4, 5}; as a global also didn't help.
I believe this is where your problem comes from:
int phil[NUM_PHIL];
and here
if(pthread_create(&philosopher[i], NULL, (void*) philosopherFun, (void*) &phil[i] ) != 0) {
more code ...
}
You're referencing a stack-allocated object (you're getting a pointer to the elements of the philo array). When the main function returns, the memory will be deleted and the other threads will still be holding on to garbage. To be sure this is the problem, move your philo array to a global scope, or allocate the array on the heap instead.
Related
I'm writing a Snake game as the first "serious" project in C. But when I try to grow the snake, program crashes with SEGFAULT error.
So, i tried to run the game in Valgrind, and got this:
==11312== 30 errors in context 7 of 7:
==11312== Invalid read of size 4
==11312== at 0x10969E: collide (game.c:238)
==11312== by 0x108FBD: main (game.c:120)
==11312== Address 0x5897c60 is 0 bytes inside a block of size 40 free'd
==11312== at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11312== by 0x109724: snake_grow (game.c:250)
==11312== by 0x108F7D: main (game.c:113)
==11312== Block was alloc'd at
==11312== at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11312== by 0x109278: start (game.c:159)
==11312== by 0x108EC0: main (game.c:91)
==11312==
==11312== ERROR SUMMARY: 80 errors from 7 contexts (suppressed: 0 from 0)
As I can suggest, I did realloc wrong and that is why the game crashes. So, the problem should be here:
void snake_grow(snake_t *snake){
snake->length++;
snake->body = realloc(snake->body, sizeof(snake->body[0]) * (snake->length));
snake->end = snake->body + snake->length - 1;
snake->end->x = snake->prev_x;
snake->end->y = snake->prev_y;
}
Or maybe I just use pointer in fuction wrong?
bool collide(snake_t *snake, block map[MAXY][MAXX]){
bool ret = FALSE;
if(map[snake->head->y][snake->head->x].collision == COLLIDABLE){
ret = TRUE;
}
for(int i = 1; i < snake->length; i++){
if(snake->body[i].x == snake->head->x){
if(snake->body[i].y == snake->head->y){
ret = TRUE;
}
}
}
return ret;
}
Strange, but I can't find anything similar to my problem. But maybe I just didn't understand solutions.
Accidentally, when I tried to make minimal reproducible example and debug, as it was advised by WhozCraig, I solve this problem.
void snake_grow(snake_t *snake){
snake->length++;
snake->body = realloc(snake->body, sizeof(snake->body[0]) * (snake->length));
snake->end = snake->body + snake->length - 1;
snake->end->x = snake->prev_x;
snake->end->y = snake->prev_y;
}
This function, besides reallocating memory, sets new address for snake->end. But there is also the snake->head, which after realloc points to the same address. So, everything that I needed to do is just set snake->head to new address.
snake->head = snake->body;
I have made a minimal-working example of how to add elements to an array with realloc. This will be expanded in a future program that has many more elements.
#include <stdio.h>//printf
#include <stdlib.h>//malloc, realloc
int main() {
//BEGIN REALLOCATE-ABLE ARRAY
unsigned int *array, loop_variable;
const unsigned int ORIGINAL_ARRAY_SIZE = 4, REALLOC_INDICES = 99;
array = malloc(ORIGINAL_ARRAY_SIZE*sizeof(unsigned int));
for (loop_variable = 0; loop_variable < ORIGINAL_ARRAY_SIZE; loop_variable++) {
array[loop_variable] = loop_variable;
}
//BEGIN REALLOCATION
for (loop_variable = 1; loop_variable < REALLOC_INDICES; loop_variable++) {
array = realloc(array,sizeof(unsigned int)*(ORIGINAL_ARRAY_SIZE+loop_variable));
array[ORIGINAL_ARRAY_SIZE+loop_variable-1] = 2*(ORIGINAL_ARRAY_SIZE+loop_variable-1);
printf("reallocate array[%d] = %d\n",ORIGINAL_ARRAY_SIZE+loop_variable-1,array[ORIGINAL_ARRAY_SIZE+loop_variable-1]);
}
//BEGIN PRINTING ARRAY VALUES
for (loop_variable = 0; loop_variable < ORIGINAL_ARRAY_SIZE+REALLOC_INDICES-1; loop_variable++) {
printf("array[%d] = %d\n",loop_variable,array[loop_variable]);
}
//BEGIN FREE ARRAY
free(array); array = NULL;
return 0;
}
This should compile on any computer with gcc or clang. I then run this program on valgrind to ensure there are no memory leaks, and I get this:
==10791== HEAP SUMMARY:
==10791== in use at exit: 0 bytes in 0 blocks
==10791== total heap usage: 99 allocs, 99 frees, 20,988 bytes allocated
==10791==
==10791== All heap blocks were freed -- no leaks are possible
==10791==
==10791== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==10791== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
However, what troubles me is that I'm using 20,988 bytes for a 101-element array. The memory use grows exponentially as the array gets bigger, instead of linearly by 4 bytes/element.
If I'm understanding Valgrind's output correctly, this array should have 4*101 elements = 404 bytes memory size, but appears to use about 50 times as much memory as it should. This is a trivial problem for such a small program, but more meaningful programs will run out of memory on this computer.
My question: is this array really using 20,988 bytes, or is Valgrind double-counting the memory?
Is there a more memory-efficient way to do this? I can't understand other examples of realloc, though I have tried to follow them as closely as I can and make this question relevant to as many users as possible.
==10791== in use at exit: 0 bytes in 0 blocks
==10791== total heap usage: 99 allocs, 99 frees, 20,988 bytes allocated
is this array really using 20,988 bytes
No, it's using 0 bytes.
“allocated” obviously means “ever allocated”, including bytes that have been freed, since the amount of memory “still allocated” is zero (and another line tells you that).
The answer, thanks to user Pascal Cuoq, is that Valgrind will sum the memory allocations for every allocation. This is why I was confused, and thought that realloc was using too much memory.
I thought that if you want to find the size of the array, you can comment out the line that says
free(array); array = NULL;
to intentionally introduce a memory bug, and Valgrind will output
==11699== LEAK SUMMARY:
==11699== definitely lost: 408 bytes in 1 blocks
==11699== indirectly lost: 0 bytes in 0 blocks
==11699== possibly lost: 0 bytes in 0 blocks
==11699== still reachable: 0 bytes in 0 blocks
==11699== suppressed: 0 bytes in 0 blocks
==11699==
==11699== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==11699== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
which gives you the true size of the array at its last iteration. There is probably a better way to do this, but my point is made.
I added improvements suggested by other users here. I had a very difficult time finding good, minimal working examples of realloc on search engines, and for future use of anyone finding this on a search engine, this is very basic minimal working example of a good, but probably not best, how to use realloc in C:
#include <stdio.h>//include printf function
#include <stdlib.h>//include malloc, realloc functions
int main() {
/*BEGIN REALLOCATE-ABLE ARRAY*/
unsigned int *array, loop_variable;
const unsigned int ORIGINAL_ARRAY_SIZE = 4, REALLOC_INDICES = 99999;
array = malloc(ORIGINAL_ARRAY_SIZE*sizeof(unsigned int));
for (loop_variable = 0; loop_variable < ORIGINAL_ARRAY_SIZE; loop_variable++) {
array[loop_variable] = loop_variable;
}
/*BEGIN REALLOCATION*/
for (loop_variable = 1; loop_variable < REALLOC_INDICES; loop_variable++) {
array = realloc(array,sizeof(unsigned int)*(ORIGINAL_ARRAY_SIZE+loop_variable));
if (array == NULL) {
printf("Array variable %d failed to reallocate :,-(\n",loop_variable);
exit(EXIT_FAILURE);
}
array[ORIGINAL_ARRAY_SIZE+loop_variable-1] = 2*(ORIGINAL_ARRAY_SIZE+loop_variable-1);
printf("reallocate array[%d] = %d\n",ORIGINAL_ARRAY_SIZE+loop_variable-1,array[ORIGINAL_ARRAY_SIZE+loop_variable-1]);
}
/*BEGIN PRINTING ARRAY VALUES*/
for (loop_variable = 0; loop_variable < ORIGINAL_ARRAY_SIZE+REALLOC_INDICES-1; loop_variable++) {
printf("array[%d] = %d\n",loop_variable,array[loop_variable]);
}
/*BEGIN FREE ARRAY*/
free(array); array = NULL;
return 0;
}
I am getting segmentation fault on line 8 in the code below.
typedef struct _my_struct {
int pArr[21];
int arr1[8191];
int arr2[8191];
int m;
int cLen;
int gArr[53];
int dArr[8191];
int data[4096];
int rArr[53];
int eArr[1024];
};
void *populate_data(void *arg) {
1 register int mask =1, iG;
2 struct _my_struct *var ;
3 var = arg; // arg is passed as initialized struct variable while creating thread
4 var->m = 13;
5 var->arr2[var->m] = 0;
6 for (iG = 0; iG < var->m; iG++) {
7 var->arr2[iG] = mask;
8 var->arr1[var->arr2[iG]] = iG;
9 if (var->pArr[iG] != 0) // pArr[]= 1011000000001
10 var->arr2[var->m] ^= mask;
11 mask <<= 1;
12 }
13 var->arr1[var->arr2[var->m]] = var->m;
14 mask >>= 1;
15 for (iG = var->m+ 1; iG < var->cLen; iG++) {
16 if (var->arr2[iG - 1] >= mask)
17 var->arr2[iG] = var->arr2[var->m] ^ ((var->arr2[iG- 1] ^ mask) << 1);
18 else
19 var->arr2[iG] = var->arr2[iG- 1] << 1;
20 var->arr1[var->arr2[iG]] = iG;
21 }
22 var->arr1[0] = -1;
}
Here is the thread function:
void main() {
unsigned int tid;
struct _my_struct *instance = NULL;
instance = (struct _my_struct *)malloc(sizeof(_my_struct ));
start_thread(&tid , 119312, populate_data, instance );
}
int
start_thread(unsigned int *tid, int stack_size, void * (*my_function)(void *), void *arg)
{
pthread_t ptid = -1;
pthread_attr_t pattrib;
pthread_attr_init(&pattrib);
if(stack_size > 0)
{
pthread_attr_setstacksize(&pattrib, stack_size);
}
else
{
pthread_attr_destroy(&pattrib);
return -1;
}
pthread_create(&ptid, &pattrib, my_function, arg);
pthread_attr_destroy(&pattrib);
return 0;
}
Once I debug it through gdb, got this error,
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffdfec80700 (LWP 22985)]
0x0000000000401034 in populate_data (arg=0x7fffffffe5d8) at Queue.c:19
19 var->arr1[var->arr2[iG]] = iG;
and its backtrace is:
#0 0x0000000000401034 in populate_data (arg=0x7fffffffe5d8) at Queue.c:159
#1 0x00007ffff7bc6971 in start_thread () from /lib/libpthread.so.0
#2 0x00007ffff792292d in clone () from /lib/libc.so.6
#3 0x0000000000000000 in ?? ()
However, I'm unable to correct the error.
Anyhelp is really appreciated.
Please show the calling code in start_thread.
It seems likely to be a stack and/or memory allocation error, the structure is pretty large (8 MB assuming 32-bit ints) and might well overflow some stack limit.
Even more possible is that it's gone out of scope, which is why the calling step must be shown.
I don't know if perhaps you've changed the names of the arrays in your _my_struct in order to hide the purpose of them (company confidential information, perhaps?), but if that's actually what you've named your arrays, I'm just going to suggest that you name them something that makes sense to you that when someone has to read your code 4 years from now, they'll have some hope of following your initialization loops & understanding what's going on. Same goes for your loop variable iG.
My next comment/question is, why are you firing off a thread to initialize this structure that's on the stack of the main thread? Which thread is going to be using this structure once it's initialized? Or are you going to make other threads that will use it? Do you have any mechanism (mutex? semaphore?) to ensure that the other threads won't start using the data until your initialization thread is done initializing it? Which sort of begs the question, why the heck are you bothering to fire off a separate thread to initialize it in the first place; you could just initialize it by calling populate_data() straight from main() and not even have to worry about synchronization because you wouldn't even be starting up any other threads until after it's done being initialized. If you're running on a multicore machine, you might get some small benefit from firing off that separate thread to do the initialization while main() goes on & does other stuff, but from the size of your struct (not tiny, but not huge either) it seems like that benefit would be very miniscule. And if you're running on a single core, you'll get no concurrency benefit at all; you'd just be wasting time firing off another thread to do it due to the context switching overhead; in a unicore environment you'd be better off just calling populate_data() directly from main().
Next comment is, your _my_struct is not huge, so it's not going to blow your stack by itself. But it ain't tiny either. If your app will always need only one copy of this struct, maybe you should make it a global variable or a file-scope variable, so it doesn't eat up stack space.
Finally, to your actual bug............
I didn't bother to try to decipher your cryptic looping code, but valgrind is telling me that you have some conditions that depend on uninitialized locations:
~/test/so$ valgrind a.out
==27663== Memcheck, a memory error detector
==27663== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==27663== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==27663== Command: a.out
==27663==
==27663== Thread 2:
==27663== Conditional jump or move depends on uninitialised value(s)
==27663== at 0x8048577: populate_data (so2.c:34)
==27663== by 0x593851: start_thread (in /lib/libpthread-2.5.so)
==27663== by 0x4BDA8D: clone (in /lib/libc-2.5.so)
==27663==
==27663== Conditional jump or move depends on uninitialised value(s)
==27663== at 0x804868A: populate_data (so2.c:40)
==27663== by 0x593851: start_thread (in /lib/libpthread-2.5.so)
==27663== by 0x4BDA8D: clone (in /lib/libc-2.5.so)
My so2.c line 34 corresponds with line 9 in your code posting above.
My so2.c line 40 corresponds with line 15 in your code posting above.
If I add the following at the top of populate_data(), these valgrind errors disappear:
memset(arg,0,sizeof(_my_struct_t));
(I modified your struct definition as follows:)
typedef struct _my_struct { int pArr[21]; ......... } _my_struct_t;
Now just because adding the memset() call makes the errors disappear doesn't necessarily mean that your loop logic is correct, it just means that now those locations are considered "initialized" by valgrind. If having all-zeros in those locations when your initialization loops begin is what your logic needs, then that should fix it. But you need to verify for yourself that such really is the proper solution.
BTW... someone suggested using calloc() to get a zeroed-out allocation (rather than using dirty stack space)... that would work too, but if you want populate_data() to be foolproof, you'll zero the memory in it and not in the caller, since (assuming you like your initialization logic as it is), populate_data() is the thing that depends on it being zeroed out, main() shouldn't have to care whether it is or not. Not a biggie either way.
A CLI program of mine compiles and runs fine on windows. Compiles fine on linux, but causes a segmentation fault when running.
I turned to stackoverflow for help, and found a few questions similar to what I was going to ask that suggested valgrind, which I just happen to have installed (woo!).
So I ran my program through valgrind, and got a depressingly large amount of output, but I shall start with the first error message:
==11951== Command: ./vt
==11951==
Loading...
Load default database? (y/n)y
Opened input file vtdb.~sv, reading contents...
==11951== Invalid write of size 1
==11951== at 0x400FA9: readnumberfromfile (in /home/rob/Documents/programming/c/vocabtest/vt)
==11951== by 0x400C21: getrecordsfromfile (in /home/rob/Documents/programming/c/vocabtest/vt)
==11951== by 0x401FFD: main (in /home/rob/Documents/programming/c/vocabtest/vt)
==11951== Address 0x53b05bb is 0 bytes after a block of size 11 alloc'd
==11951== at 0x4C28FAC: malloc (vg_replace_malloc.c:236)
==11951== by 0x400EAC: readnumberfromfile (in /home/rob/Documents/programming/c/vocabtest/vt)
==11951== by 0x400C21: getrecordsfromfile (in /home/rob/Documents/programming/c/vocabtest/vt)
==11951== by 0x401FFD: main (in /home/rob/Documents/programming/c/vocabtest/vt)
==11951==
...finished.
1180 entries read from vtdb.~sv.
The problem seems to be in readnumberfromfile, and I've looked through it, and I can't seem to find what's wrong with it!
Can anyone shed some light?
int readnumberfromfile (int maxvalue,char separator)
{
int number, i=0;
char ch;
char * buff = (char *)malloc(11);//allocate enough space for an 10-digit number and a terminating null
if (!buff) {printf("Memory allocation failed!\n");return 0;}//return 0 and print error if alloc failed
if (!maxvalue) maxvalue=MAXINTVALUE;
ch=getc(inputfile);
while (!isdigit(ch))
{
if (ch == separator||ch=='\n'||ch==EOF) {fprintf(stderr,"Format error in file\n");return 0;}//if no number found(reached separator before digit), print error and return 0
ch = getc(inputfile);//cycle forward until you reach a digit
}
while (i<11 && ch!=separator && ch!='\n')//stop when you reach '~', end of line, or when number too long
{
buff[i++]=ch;
ch = getc(inputfile); //copy number from file to buff, one char at a time
}
buff[i] = '\0';//terminate string
number = atoi(buff)<=maxvalue ? atoi(buff) : maxvalue;//convert string to number and make sure it's in range
free(buff);
return number;
}
This is called from getrecordsfromfile if that's of any use:
void getrecordsfromfile(char * inputfilename,char separator)
{
int counter = 0;
struct vocab * newvocab;
struct listinfo * newvocablist;
if (!(inputfile = fopen(inputfilename, "r")))
{
printf("Unable to read input file. File does not exist or is in use.\n");
}
else
{
printf("Opened input file %s, reading contents...\n",inputfilename);
while (!feof(inputfile))
{
newvocab = (struct vocab *)malloc(sizeof(struct vocab));
if (!newvocab)
{
printf("Memory allocation failed!\n");
return;
}
else
{
newvocab->question=readtextfromfile(MAXTEXTLENGTH,separator);
newvocab->answer=readtextfromfile(MAXTEXTLENGTH,separator);
newvocab->info=readtextfromfile(MAXTEXTLENGTH,separator);
newvocab->hint=readtextfromfile(MAXTEXTLENGTH,separator);
newvocab->right=readnumberfromfile(1,separator);
newvocab->counter=readnumberfromfile(0,separator);
newvocab->known=readnumberfromfile(3,separator);
switch (newvocab->known)
{
case 0: newvocablist = &n2l;break;
case 1: newvocablist = &norm;break;
case 2: newvocablist = &known;break;
case 3: newvocablist = &old;break;
}
addtolist(newvocab,newvocablist);
if (newvocab->question==NULL||newvocab->answer==NULL)
{
printf("Removing empty vocab record created from faulty input file...\n");
removefromlist(newvocab,newvocablist,1);
}
else counter++;
}
}
fclose(inputfile);
printf("...finished.\n%i entries read from %s.\n\n",counter,inputfilename);
}
return;
}
Full source can be gitted from https://github.com/megamasha/Vocab-Tester
A couple of notes: I am trying to help myself, I have done my research, looked at similar questions and found out about valgrind myself.
I am still a relative beginner though, and while I appreciate solutions (WHAT to do to fix it), yet more useful is knowledge (HOW to fix or avoid it myself next time). I am here (and very keen) to learn.
buff[i] = '\0';//terminate string
in here i == 11, since you allocated only 11 chars, and while condition ends when i=11.
so, you access a memory you did not allocate.
the behavior for this situation is not defined.
you can solve this by allocating one extra character on your malloc.
int number, i=0;
...
while (i<11 ...
You are reading up to eleven digits for i = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and 10. And then trying to stick the \0 in twelfth slot buff[11].
It's called an "off by one error".
So the fix depends on what you want to change. If you want to accept 11 characters, change the malloc of buff. If you want to only accept 10, then change the while condition.
Invalid write of size 1
You're probably writing a char
Address 0x53b05bb is 0 bytes after a block of size 11 alloc'd
You've only just overflowed something of size 11
Both in readnumberfromfile
This is suspiciously related (by the sizes):
char * buff = (char *)malloc(11);
This will be done with i = 11 after the loop, which is past the end of the allocation:
buff[i] = '\0'
As wormsparty says you can get valgrind to be more helpful, by getting debug symbols in your binary.
For later, if you compile with -g, valgrind will show you exactly at which line the segfault happened.
The following code is an example from the NCURSES menu library. I'm not sure what could be wrong with the code, but valgrind reports some problems. Any ideas...
==4803== 1,049 (72 direct, 977 indirect) bytes in 1 blocks are definitely lost in loss record 25 of 36
==4803== at 0x4C24477: calloc (vg_replace_malloc.c:418)
==4803== by 0x400E93: main (in /home/gerardoj/a.out)
==4803==
==4803== LEAK SUMMARY:
==4803== definitely lost: 72 bytes in 1 blocks
==4803== indirectly lost: 977 bytes in 10 blocks
==4803== possibly lost: 0 bytes in 0 blocks
==4803== still reachable: 64,942 bytes in 262 blocks
Source code:
#include <curses.h>
#include <menu.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#define CTRLD 4
char *choices[] = {
"Choice 1",
"Choice 2",
"Choice 3",
"Choice 4",
"Choice 5",
"Choice 6",
"Choice 7",
"Exit",
}
;
int main()
{
ITEM **my_items;
int c;
MENU *my_menu;
int n_choices, i;
ITEM *cur_item;
/* Initialize curses */
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
/* Initialize items */
n_choices = ARRAY_SIZE(choices);
my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
for (i = 0; i < n_choices; ++i) {
my_items[i] = new_item(choices[i], choices[i]);
}
my_items[n_choices] = (ITEM *)NULL;
my_menu = new_menu((ITEM **)my_items);
/* Make the menu multi valued */
menu_opts_off(my_menu, O_ONEVALUE);
mvprintw(LINES - 3, 0, "Use <SPACE> to select or unselect an item.");
mvprintw(LINES - 2, 0, "<ENTER> to see presently selected items(F1 to Exit)");
post_menu(my_menu);
refresh();
while ((c = getch()) != KEY_F(1)) {
switch (c) {
case KEY_DOWN:
menu_driver(my_menu, REQ_DOWN_ITEM);
break;
case KEY_UP:
menu_driver(my_menu, REQ_UP_ITEM);
break;
case ' ':
menu_driver(my_menu, REQ_TOGGLE_ITEM);
break;
case 10:
{
char temp[200];
ITEM **items;
items = menu_items(my_menu);
temp[0] = '\0';
for (i = 0; i < item_count(my_menu); ++i)
if(item_value(items[i]) == TRUE) {
strcat(temp, item_name(items[i]));
strcat(temp, " ");
}
move(20, 0);
clrtoeol();
mvprintw(20, 0, temp);
refresh();
}
break;
}
}
unpost_menu(menu);
free_item(my_items[0]);
free_item(my_items[1]);
free_item(my_items[2]);
free_item(my_items[3]);
free_item(my_items[4]);
free_item(my_items[5]);
free_item(my_items[6]);
free_item(my_items[7]);
free_menu(my_menu);
endwin();
}
According to the NCURSES Programming Howto, using the menus library requires the following steps:
Initialize curses
Create items using new_item(). You can specify a name and description for the items.
Create the menu with new_menu() by specifying the items to be attached with.
Post the menu with menu_post() and refresh the screen.
Process the user requests with a loop and do necessary updates to menu with menu_driver.
Unpost the menu with menu_unpost()
Free the memory allocated to menu by free_menu()
Free the memory allocated to the items with free_item()
End curses
From what I can tell from your code:
You don't unpost the menu (which might cause a leak, or it might just risk garbling the screen).
The menu is freed after the items are freed (which I guess may or may not be a problem depending on how ncurses is implemented).
Only items 0 and 1 of the 8-element array of items are freed. This is probably a leak.
The my_items array of pointers is never freed. This is certainly a leak.
As #lh3 said, compiling with the -g option will let Valgrind give the line number of lost memory.
Edit (in response to your comment): my_items is a dynamically allocated array of pointers to dynamically created menu items. In other words, you have one block of dynamic memory, and it contains a bunch of pointers to a bunch of dynamically allocated ncurses structures (menu items). So, to clean up once you're done, you need to free each of the dynamically allocated ncurses structures, and then you need to free the block of memory that held the pointers to those structures.
In other words, every calloc or malloc needs a free, every new_item needs a free_item, and so on.
for (i = 0; i < n_choices; ++i) {
free_item(my_items[i]);
}
free(my_items);
Something to note with Valgrind (this comes up on the Valgrind user's mailing list often):
still reachable: 64,942 bytes in 262 blocks
This is just referencing blocks that were still reachable in main() at exit, which (under any modern kernel) would just be reclaimed by the OS anyway.
While its good practice to explicitly free() every single allocated block before exit is called, this is not technically leaked memory, since it still could be reached at the time of exit.
Focus on directly, indirectly and possibly lost blocks as Josh Kelly has suggested. This is just a supplement to the answers that have already pointed out the likely sources of leaks.
try running valgrind with --leak-check=full maybe?
free_item(my_items[7]);
free(my_items);