c: valgrind "Conditional jump or move depends on uninitialised value(s)" - c

I'm getting an error in valgrind and don't know what is wrong.
The error is:
valgrind output:
==1112== Conditional jump or move depends on uninitialised value(s)
==1112== at 0x402BF0D: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
And it states the problem occurs on line 226:
if(reallocate ==TRUE)
{
char** temp_values = NULL;
temp_values = (char**) realloc(theBoard->_values, theBoard->_size_r*sizeof(char*) );
if(temp_values!=NULL)
{
theBoard->_values = temp_values;
} else
{
reportError(MEM_OUT);
return FALSE;
}
int i = 0;
for (i=0; i<theBoard->_size_r; i++)
{
char* temp_values_c = NULL;
HERE( line 226)-> temp_values_c = realloc(theBoard->_values[i], theBoard->_size_c*sizeof(char) );
if(temp_values_c != NULL)
{
theBoard->_values[i] = temp_values_c;
} else
{
reportError(MEM_OUT);
return FALSE;
}
}
// initialize extra memory
if(row_out_bound)
{
init(theBoard,prev_size_r,0);
}
if(col_out_bound)
{
init(theBoard,0, prev_size_c);
}
}
Why is this happening and how can i fix it?

The problem is theBoard->_values[i] is not initialized since it comes straight from realloc (temp_values = ...).
EDIT
Can you elaborate please?
I thought you'd never ask. The function realloc returns a chunk of memory of the specified size, with no guarantees regarding its contents. So for all practical purposes you should assume anything realloc returns contains garbage. In your code you take that (potential) garbage and on line 226 you tell realloc:
Here's this pointer that's like totally valid and all. It's NULL or I previously obtained it from malloc. Can you realloc it to this size? And that's not true! The actual value contained by theBoard->_values[i] could be anything.
What you want is a loop that does theBoard->_values[i] = NULL, or maybe use malloc instead of realloc on line 226.

Related

Right way to handle errors and free memory in C

in some functions I need to allocate memory with malloc() and have several if..else statements, like the pseudo-code illustrates:
allocate memory
if condition_1
do_stuff
if condition_2
do_more_stuff
else
error
else
error
free allocated memory
return
So I allocate memory at the beginning and it would freed if everything would work well. But currently the error functions only print an error message and exit the porgram. But as I have read often that not freeing memory although when the program exits and the OS handles normally handles the freeing afterwards, it no good style. How can I free the money in a lazy way? Do I have to write an error function that takes every pointer to the memory I have allocated that has to be freed,the pointery may be of different data types? Or should i put free(ptr) before calling the error function? An error function that takes an array of pointer with data type void and freeing than all, would do this the trick?
I have two solutions.
You can put a label where you put the call to free and error:
void function(void)
{
Memory *p = malloc(sizeof(*p));
if (condition_1) {
do_stuff();
if (condition_2) {
do_more_stuff();
} else {
goto err;
}
} else {
goto err;
}
free(p);
return;
err:
free(p);
error();
}
You can also use a flag to mark an error:
void function(void)
{
Memory *p = malloc(sizeof(*p));
bool err = false;
if (condition_1) {
do_stuff();
if (condition_2) {
do_more_stuff();
} else {
err = true;
}
} else {
err = true;
}
free(p);
if (err)
error();
}
I think that the second solution looks best in this case but both of them work equally well.
Don't use goto. Use a one-time while. Also, if you need an error flag, default it to true instead of false to save code:
...malloc...
err = 1;
do {
...
if <condition> break;
...
if <condition> break;
...
if <condition> break;
...
err = 0;
} while (0);
...free...
if (err) ...
From what I understand you care about freeing all the memory when you exit the program because of error but dont want to handle all the pointers manually.
Here is an interesting thought, write a function allocMemory that returns the result of malloc but also puts the pointer into a linked list, then freeMemory that removes it from the list, and finally release all function that iterates over the list and frees all the pointers.
Use the allocMemory and freeMomory function instead of malloc and free, and call the freeMemory function in case of error.

Memory fault - c

I do not know why I get Memory fault (core dumped) when I run this code
if (flg == 4) // PIPE
{
char **cmds;
char ***cmdarg;
int j=0;
cmds = split_str(cmd, "|");
for (i = 0; args[i] != NULL; i++)
{
if (strcmp(args[i], "|") == 1)
{
cmdarg[j][i]=args[i];
}
else
{
cmdarg[j][i+1] = NULL;
j++;
}
printf("%s\n",cmdarg[j][i]);
}
}
I am not so expert with pointers and arrays
cmdarg is not initialized. And I'm sure that GCC, when invoked as gcc -Wall -g, would have warned you about that.
You could keep its length, e.g.
int cmdarglen = 0;
Then initialize it to some suitable default size:
#define INITIAL_CMDARG_SIZE 10
cmdarg = calloc(INITIAL_CMDARG_SIZE, sizeof(*cmdarg));
if (!cmdarg) { perror("calloc cmdarg initial"); exit (EXIT_FAILURE); );
cmdarglen = INITIAL_CMDARG_SIZE;
then grow it when needed, e.g.
if (j >= cmdarglen) {
int newcmdarglen = 5*j/4+10;
char***newcmdarg = calloc(newcmdarglen, sizeof(*cmdarg));
if (!newcmdarg)
{ perror("calloc growing cmdarg"); exit(EXIT_FAILURE); };
memcpy (newcmdarg, cmdarg, sizeof(*cmdarg)*j);
free (cmdarg);
cmdarg = newcmdarg;
}
to be inserted appropriately inside your for loop. Of course, you probably need to initialize each element of cmdarg (by allocating them individually).
Don't forget to free(cmdarg) later.
At last, learn how to use the gdb debugger and valgrind memory leak detector.
You never initialize the cmdarg variable in you code. It will have an unspecified value, so when you dereference it, there is undefined behavior. In your case, this manifest by a segmentation fault.
I don't know what your code is trying to do, but what I can see is that you are reffering to an uninitialized variable 'cmdarg'.Another adivce: when possible (and I think that nearly always it is possible) try to avoid three levels of indirections (***).

malloc and free in loops. object was probably modified after being freed.?

I have created a multilevel cache simulator, and to find the best performance cache, I have made loops that loop for quite a while.
Since each loop is allocating memory, with malloc, I freed up whatever it malloced, but I get this error when I run:
"incorrect checksum for freed object - object was probably modified after being freed"
Here's part of the code
Here's where it allocates memory:
/* cache1 */
if (S1 == 0) {
L1 = 1;
d_Cache1.cache_Array = (aBlock *)malloc((int)pow(2, (C1-B1)) * sizeof(aBlock));
/* static int cache1[(int)pow(2,(C1 - B1))]; */
} else if (S1 == C1-B1) {
L1 = 2;
f_Cache1.cache_Array = (aBlock *)malloc((int)pow(2, (C1-B1)) * sizeof(aBlock));
} else {
L1 = 3;
s_Cache1.cache_Array = malloc((int)pow(2, (C1 - S1 - B1))*sizeof(aBlock *));
if(s_Cache1.cache_Array == NULL){
fprintf(stderr, "out of memory\n");
return;
}
for (i = 0; i < (int)pow(2, (C1 - S1 - B1)); i++) {
s_Cache1.cache_Array[i] = malloc((int)pow(2, S1) * sizeof(aBlock));
if (s_Cache1.cache_Array[i] == NULL) {
fprintf(stderr, "out of memory\n");
return;
}
}
sc_Count1 = malloc((int)pow(2,S1) * sizeof(aBlock));
for (i = 0; i < (int)pow(2, S1); i++) {
sc_Count1[i] = 0;
}
}
and after performing everything, it frees up:
//cache1
if (S1 == 0) {
free(d_Cache1.cache_Array);
} else if (S1 == C1-B1) {
free(f_Cache1.cache_Array);
} else {
for (i = 0; i < (int)pow(2, (C1 - S1 - B1)); i++) {
free(s_Cache1.cache_Array[i]);
}
free(s_Cache1.cache_Array);
free(sc_Count1);
}
What could be causing this memory issue?
I'm freeing up the exact memory that i allocate, and value of S1, C1, B1 never changes until next loop.
Quite possibly the problem is in the middle - at least, I don't see where you do anything with the memory you malloc. Are you just zeroing out the array, or do you do something else with it? incorrect checksum for freed object - object was probably modified after being freed often comes from smashing the memory contents around the memory you malloc'd (that is, index out of bounds) or doing exactly what it's telling you - modifying the memory contents after freeing them - and that's my best guess as to what's happening.
As a measure of protection, when in debug mode, some compilers will put in a checksum around the memory to see if it gets modified after being freed, and if you do modify it, it won't match the checksum. The compiler is telling you you're messing with the contents of a chunk of memory that you have freed. Often times, the extra cost of check only happens when mallocing or freeing, so that's why it seems to be associated with those calls.
You may be tracking your malloc and frees just fine, but the next thing I would look at is the state of the memory when you write into it.
first
s_Cache1.cache_Array=malloc(...
then
s_Cache1.cache_Array[i]=malloc(..
Looks a bit suspicious in my eyes. malloc something within something already malloced?

*glibc detected double free or corruption() * message!

The following deleteNode function when I run the program gets these:
* glibc detected free(): invalid next size (normal): 0x000000000103dd90 **
Even i make the ' free(here); ' a comment,i get the above message.
I dont think that the other 'free' calls provokes a problem like that. But I cant see why this would be wrong. :/
struct List *deleteNode(int Code,int i,char* Number)
{
struct List *here;
here=Head;
for (here; here!=Tail; here=here->next)
{
if ( (here->number==Number) && (here->code==Code) )//found node on the List
{
if (here->previous==Head) //delete from beginning
{
Head=here->next;
here->next->previous=Head;
}
else if (here->next==Tail) //delete from the end
{
here->previous->next=Tail;
Tail=here->previous;
}
else //delete from the middle of the list
{
here->previous->next=here->next;
here->next->previous=here->previous;
}
break;
}
}
free (here);
}
EDIT:
if i used and understand valgring well then the problem is on my main function.
i have also there some 'free' but i changed deleteNode before this message so i thought that the problem was on the deleteNode function.
Now,there is no free() invalid next size.... but unfortunately this:
glibc detected * : double free or corruption (out): 0x00007fff1aae9ae0 *
:(
A part of the main:
FILE *File;
if ( ( File=fopen("File.txt","r")) !=NULL )
{
int li = 0;
char *lin = (char *) malloc(MAX_LINE * sizeof(char));
while(fgets(lin, MAX_LINE, eventFile) != NULL)
{
token = linetok(lin, " ");
if(token != NULL)
{
int i,code,nodeID;
char *number;
char *event;
for(i = 0; token[i] != NULL; i += 1)
{
code=atoi(token[0]);
strcpy(event,token[1]);
nodeID=atoi(token[2]);
strcpy(number,token[3]) ;
int i;
if (!strcmp(event,"add"))
{
add_to_List(code,i,number);
}
else if(!strcmp(event,"delete"))
{
deleteNode(eventNo,i,number);
}
free(event);
free(phoneNumber);
}
free(token);
}
else
{
printf("Error reading line %s\n", lin);
exit(1);
}
}
}
else
{
printf("Error opening file with the events.\nEXIT!");
exit(0);
}
debugging it...
multiple definition of main'
pro:(.text+0xce0): first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.4.1/crtend.o:(.dtors+0x0): multiple definition ofDTOR_END'
pro:(.dtors+0x8): first defined here
/usr/bin/ld: warning: Cannot create .eh_frame_hdr section, --eh-frame-hdr ignored.
/usr/bin/ld: error in pro1(.eh_frame); no .eh_frame_hdr table will be created.
collect2: ld returned 1 exit status
"Invalid next size" means that glibc has detected corruption in your memory arena.
You have overwritten valuable accounting information that's stored in between your allocated blocks.
With each block that malloc gives you, there is some accounting information stored close by. When you overwrite this information by, for example, writing 128 characters to a 20-character buffer, glibc may detect this the next time you try to free (or possibly allocate) some memory.
You need to find the root cause of this problem - it's not the free itself, that's just where the problem is being detected. Somewhere, some of your code is trashing memory and a memory analysis tool like valgrind will be invaluable here.
If the node is not found in the list, you will free the Tail node at the end of the function, without updating Tail to point to anything valid again.
Further using the list and the now deallocated Tail can easily result in memory corruption that might later be detected by glibc with a message like the one you got.
Also note that in (here->number==Number) you are comparing two pointers, not the values those pointers point to. I'm not sure if that's what you want.

valgrind conditional jump or move depends on uninitialised value

I want to fix problem reported by valgrind:
==7182== Conditional jump or move depends on uninitialised value(s)
==7182== at 0x40EC75C: strstr (in /lib/libc-2.9.so)
==7182== by 0x804A977: search_graph_begin (compression.c:462)
==7182== by 0x804AB60: search_graph_end (compression.c:497)
==7182== by 0x804AA97: search_graph_begin (compression.c:477)
==7182== by 0x804B59A: do_g_decompress (compression.c:767)
==7182== by 0x804996C: main (server.c:302)
my relevant part of code is:
void search_graph_begin(char* buf, FILE *dest,int* graph_count,int extension,
char* graphs,char* directory,int have)
{
char* begingraph = NULL;
begingraph = strstr(buf,"<GRAPH>");
if (begingraph != NULL)
{
if ( (int)(begingraph - buf) > 1)
{
printf("(int)(begingraph-buf) %d\n",(int)(begingraph-buf));
xwrite(dest,buf,(int)(begingraph-buf));
}
(*graph_count)++;
sprintf(graphs,"%s/tmp/graphs%d/graph%d",directory,extension,(*graph_count));
/*open file to save received graph data*/
FILE* graphfile = fopen(graphs,"wb");
if (graphfile == NULL)
fprintf(stderr,"could not create graph file\n");
search_graph_end(begingraph+strlen("<GRAPH>")+1,graphfile,dest,graph_count,extension,graphs,directory,
have-(begingraph+strlen("<GRAPH>")+1-buf));
}
else
{
if (have > 1)
xwrite(dest,buf,have);
buf = NULL;
}
}
void search_graph_end(char* buf, FILE* graphfile, FILE *dest,int* graph_count,int extension,
char* graphs,char* directory,int have)
{
char* endgraph = NULL;
endgraph = strstr(buf,"<GRAPH/>");
if (endgraph != NULL)
{
xwrite(graphfile,buf,sizeof(char)*(endgraph-buf));
fclose(graphfile);
search_graph_begin(endgraph+strlen("<GRAPH/>")+1,dest,graph_count,extension,graphs,directory,
have-(endgraph+strlen("<GRAPH/>")+1-buf));
}
else
{
if (have > 1)
xwrite(graphfile,buf,have);
buf = NULL;
}
}
the program runs fine under valgrind but its not the case when not. The idea of the program is to read in loop a buffer and write text between valise and in different files
A program that crashes in one environment, but not in a slightly different environment (under Valgrind, in gdb, different -O) is a telltale sign of undefined behaviour caused by a bug. The thing is though that the actual bug (eg. an off-by-one write) can be located anywhere in your program. The stack trace only tells you where the bug was detected. You need to look beyond the stack trace to find the actual bug. What part of your program is responsible for initializing the value that Valgrind complains about?

Resources