Memory fault - c - 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 (***).

Related

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

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.

Why does segmentation fault (core dumped) error apply to my C program?

I keep getting this error and I am not sure how it applies to my program. This is my program.
#include<stdio.h>
#include<stdlib.h>
int nextword(char *str);
void main(void)
{
char *str = "Hello! Today is a beautiful day!!\t\n";
int i = nextword(str);
while(i != -1)
{
printf("%s\n",&(str[i]));
i = nextword(NULL);
}
}
int nextword(char *str)
{
// create two static variables - these stay around across calls
static char *s;
static int nextindex;
int thisindex;
// reset the static variables
if (str != NULL)
{
s = str;
thisindex = 0;
// TODO: advance this index past any leading spaces
while (s[thisindex]=='\n' || s[thisindex]=='\t' || s[thisindex]==' ' )
thisindex++;
}
else
{
// set the return value to be the nextindex
thisindex = nextindex;
}
// if we aren't done with the string...
if (thisindex != -1)
{
nextindex = thisindex;
// TODO: two things
// 1: place a '\0' after the current word
// 2: advance nextindex to the beginning
// of the next word
while (s[nextindex] != ' ' || s[nextindex] != '\n' || s[nextindex] != '\t')
{
if ( s[nextindex] == '\0')
return -1;
else
{
nextindex++;
if (s[nextindex]==' '||s[nextindex]=='\n'||s[nextindex]=='\t')
str[nextindex]='\0';
}
}
}
return thisindex;
}
My program is supposed to have an output to the console of
Hello!
Today
is
a
beautiful
day!!
You are trying to change a String literal. This results in undefined behavior, such as a segfault.
str[nextindex]='\0'
and in Here, str is the parameter of nextWord(), which is:
char *str = "Hello! Today is a beautiful day!!\t\n";
int i = nextword(str);
Since "Hello! Today is a beautiful day!!\t\n" is a string literal - changing it is udnefined behavior, and in your case (luckily) it caused a seg-fault.
You should compile with all warnings and debugging info enabled (if using GCC e.g. on Linux, that means compiling with gcc -Wall -g).
Then you should learn how to use the debugger (i.e. gdb on Linux) and possibly a leak detector like valgrind
a segmentation fault may happen if you dereference some "bad" pointer, e.g. a NULL one or an uninitialized one. It also may happen if you write into a read-only segment (you are probably overwriting a string literal which is put into a read-only -so called .text or .rodata- segment)
Taking account of every warning of the compiler (and enabling them) and using a debugger are essential skills of any C programmer.
Please give nextindex a initial value

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.

Running out of memory.. How?

I'm attempting to write a solver for a particular puzzle. It tries to find a solution by trying every possible move one at a time until it finds a solution. The first version tried to solve it depth-first by continually trying moves until it failed, then backtracking, but this turned out to be too slow. I have rewritten it to be breadth-first using a queue structure, but I'm having problems with memory management.
Here are the relevant parts:
int main(int argc, char *argv[])
{
...
int solved = 0;
do {
solved = solver(queue);
} while (!solved && !pblListIsEmpty(queue));
...
}
int solver(PblList *queue) {
state_t *state = (state_t *) pblListPoll(queue);
if (is_solution(state->pucks)) {
print_solution(state);
return 1;
}
state_t *state_cp;
puck new_location;
for (int p = 0; p < puck_count; p++) {
for (dir i = NORTH; i <= WEST; i++) {
if (!rules(state->pucks, p, i)) continue;
new_location = in_dir(state->pucks, p, i);
if (new_location.x != -1) {
state_cp = (state_t *) malloc(sizeof(state_t));
state_cp->move.from = state->pucks[p];
state_cp->move.direction = i;
state_cp->prev = state;
state_cp->pucks = (puck *) malloc (puck_count * sizeof(puck));
memcpy(state_cp->pucks, state->pucks, puck_count * sizeof(puck)); /*CRASH*/
state_cp->pucks[p] = new_location;
pblListPush(queue, state_cp);
}
}
}
free(state->pucks);
return 0;
}
When I run it I get the error:
ice(90175) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Bus error
The error happens around iteration 93,000.
From what I can tell, the error message is from malloc failing, and the bus error is from the memcpy after it.
I have a hard time believing that I'm running out of memory, since each game state is only ~400 bytes. Yet that does seem to be what's happening, seeing as the activity monitor reports that it is using 3.99GB before it crashes. I'm using http://www.mission-base.com/peter/source/ for the queue structure (it's a linked list).
Clearly I'm doing something dumb. Any suggestions?
Check the result of malloc. If it's NULL, you might want to print out the length of that queue.
Also, the code snippet you posted didn't include any frees...
You need to free() the memory you've allocated manually after you're done with it; dynamic memory doesn't just "free itself"

Resources