Troublesome 2D array realloc heap error - c

Code snippet follows.
Background: Revising a old C windows application to communicate with new instruments (while maintaining as much old code as possible), which requires the addition of new features. In this case I am copying file names from a directory into a 2D array to populate a list of the file names.
While debugging, the program gets to the realloc call (the second realloc, as the first is skipped by the if statement) and then breaks with the error which precedes the code snippet below.
At the time of realloc, WFMLIST has been allocated, with the first element initialized to 0, and NbItemWFMLIST = 1. So my question is, does anybody know why this error might be occurring? The memory allocation and reallocation worked before I added the directory searching and copying components. Is it DLL releated? I have tried many things (suggestions from similar errors on Stackoverflow), including replacing the realloc with a free() and then calloc() and received the same error.
Also, ffd is correctly finding the directory and providing the appropriate string in ffd.cFileName.
Please let me know if I can provide more information. Thanks.
HEAP[vhf.exe]: Heap block at 01068980 modified at 01068989 past
requested size of 1 Windows has triggered a breakpoint in vhf.exe.
This may be due to a corruption of the heap, which indicates a bug in
vhf.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while vhf.exe has focus.
char **WMFLIST=NULL;
long int NbItemWFMLIST = 0;
unsigned int playback_bytes;
WIN32_FIND_DATA ffd; //Added for directory search
LARGE_INTEGER filesize; //
TCHAR szDir[MAX_PATH]; //
TCHAR *pwrkDir;
size_t length_pwrkDir;
HANDLE hFind = INVALID_HANDLE_VALUE;
pwrkDir = (TCHAR *)calloc(5, sizeof(TCHAR));
if(WFMLIST==NULL)
{
WFMLIST=(char **)calloc(NbItemWFMLIST,sizeof(char *));
if(WFMLIST != NULL)
{
WFMLIST[0]=(char *)calloc(13,sizeof(char));
if(WFMLIST[0]==NULL)
{
MessageBox(hWnd,"CALLOC WMLIST[0]==NULL","Memory allocation error",MB_OK);
NbItemWFMLIST=0;
return(0); **error check
}
else
{
NbItemWFMLIST=1;
sprintf_s(&WFMLIST[NbItemWFMLIST-1][0],MAX_PATH,"\0");
}
}
else
{
**error
}
}
else
{
WFMLIST = (char **)realloc((void *) WFMLIST,sizeof(char *));
if(WFMLIST==NULL)
{
**error check
}
else
{
NbItemWFMLIST=1;
sprintf(&WFMLIST[NbItemWFMLIST-1][0],"\0");
}
}
if((tawg->status = GetCurrentDirectory(MAX_PATH,pwrkDir))==SIG_SUCCESS) //Locate the current working directory
{
**Error check
}
sprintf_s(pwrkDir, MAX_PATH, "%s\\Waveforms", pwrkDir); //Append directory with Waveform folder
strcpy(szDir, pwrkDir);
strcat(szDir,"\\*");
hFind = FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind)
{
**error check
}
while (FindNextFile(hFind, &ffd) != 0);
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
**error check
}
else
{
WFMLIST=(char **)realloc((void*)WFMLIST,((NbItemWFMLIST+1)*sizeof(char *)));
if (WFMLIST[NbItemWFMLIST]==NULL)
{
**error
}
else
{
WFMLIST[NbItemWFMLIST]=(char *)calloc(13,sizeof(char));
if (WFMLIST[NbItemWFMLIST]==NULL)
{
**error
}
else
{
sprintf(&WFMLIST[NbItemWFMLIST][0],"%s",ffd.cFileName);
NbItemWFMLIST=NbItemWFMLIST+1;
}
}
}
}

Related

How to free all memory blocks of a picture using quadree structure with different cases?

Few weeks ago, I was trying to implement a function to display a quadtree. My current problem is concerning the same work, so I pass you this link for all the context: How to display composed quadtrees using C language?
(I'm using a few features that come from this post)
the quadtree structure:
typedef struct block_image
{
int allBlack; //boolean
struct block_image * son[4];
}block_image;
typedef block_image *image;
Currently, I’m working on a function to free all memory blocks of a quadtree. For example, if a quadtree is white, there is nothing to do because the pointer to the structure is already NULL. If a quadtree is black, we free the pointer and set it to NULL. Else, if it is a composed picture, we take care of freeing the space of the different sons.
summary: returns all blocks of an image to the memory.
My current program:
void freeMemory(image myImage)
{
if(myImage == NULL)
{
return;
}
else if(myImage->allBlack)
{
free(myImage);
myImage = NULL;
}
else
{
freeMemory(myImage->son[0]);
freeMemory(myImage->son[1]);
freeMemory(myImage->son[2]);
freeMemory(myImage->son[3]);
}
}
However, I am not sure how to check my function.
For exemple, I decided to create a white quadree and a black quadtree. But when I used freeMemory fonction and normalDisplay to see the representation of the two quadrees before and after, there was no difference.
printf("\nfreeMemory\n\n");
image white = Build_white();
image black = Build_black();
printf("before\n");
normalDisplay(black);
printf("\n");
printf("after\n");
freeMemory(black);
normalDisplay(black);
printf("\n");
printf("before\n");
normalDisplay(white);
printf("\nafter\n");
freeMemory(white);
normalDisplay(white);
printf("\n");
The result:
As you can see, there was no difference between display before and after memory.
And this is the simplest case, after that it should also work with composed images,e.g.
N +BBNB B +N+NNB+NBNNBN.
Someone advised me to use valgrind, telling me that for my program to work, there must be as many malloc() as free(). But I don't really know how to interpret the results (and if it is really useful).
the result (My variable names was not in english so, affichageNormal == normalDisplay, Rendmemoire == freeMemory and Construit_noir == Build_black)
P.S. I also have two function isWhite and isBlack to tell if a picture is black (no white elements) or white (no black element):
int isWhite(image myImage)
{
if(myImage == NULL)
{
return 1;
}
else if(myImage->allBlack)
{
return 0;
}
else if(isWhite(myImage->son[0]) && isWhite(myImage->son[1]) && isWhite(myImage->son[2]) && isWhite(myImage->son[3]))
{
return 1;
}
return 0;
}
int isblack(image myImage)
{
if(myImage == NULL)
{
return 0;
}
else if(myImage->allBlack)
{
return 1;
}
else if(isBlack(myImage->son[0]) && isBlack(myImage->son[1]) && isBlack(myImage->son[2]) && isBlack(myImage->son[3]))
{
return 1;
}
return 0;
}
It may be useful for the function.
Edit:
In case of doubt I also add the code of normalDisplay :
void normalDisplay(image myImage)
{
if(myImage == NULL)
{
printf("B");
}
else if(myImage->allBlack)
{
printf("N");
}
else
{
printf("+");
normalDisplay(myImage->son[0]);
normalDispay(myImage->son[1]);
normalDisplay(myImage->son[2]);
normalDisplay(myImage->son[3]);
}
}
A robust way to free the memory from the quadtree is to make sure you feedback that a pointer no longer is pointing to valid memory. Since your current freeMemory only takes an block_image pointer, the function cannot convey this information back to the caller.
Better would be to change its interface to provide this facitily with another level of indirection.
void freeMemory(image *myImage) {
if (myImage != NULL && *myImage != NULL) {
int sonSize = sizeof((*myImage)->son) / sizeof((*myImage)->son[0]);
while (sonSize) freeMemory(&(*myImage)->son[--sonSize]);
free(*myImage);
*myImage = NULL;
}
}
On a side note, your original freeMemory does have a memory leak, but hoping you can figure that out.
This way, *myImage = NULL will convey this change to the caller. On the calling side it would look something like this:
puts("\nfreeMemory\n");
image white = Build_white();
image black = Build_black();
puts("before");
normalDisplay(black);
puts("");
puts("after");
freeMemory(&black);
normalDisplay(black);
puts("");
puts("before");
normalDisplay(white);
puts("\nafter");
freeMemory(&white);
normalDisplay(white);
puts("");
With this your normalDisplay will better provide you with an "image" of the situation.

How to modify an existing YAML node in C?

I am not C programmer but have recently taking interest in it. I am trying to modify a node of a YAML file using the C libyaml library. When I try to modify the node from an event scalar data the compiler doesn't complain but I get segmentation fault errors.
while (!done)
{
/* Get the next token. */
if (!yaml_parser_parse(&parser, &event))
goto parser_error;
//yaml_parser_scan(&parser, &token);
/* Check if this is the stream end. */
if(beginServerNodes && event.type == 8) {
beginServerNodes = 0;
}
if (event.type == YAML_SCALAR_EVENT) {
if(beginServerNodes == 1) {
//I WANT TO MODIFY THIS VALUE
printf("%s\n", event.data.scalar.value);
}
if(strcmp("servers",event.data.scalar.value) == 0) {
beginServerNodes = 1;
}
}
if (event.type == YAML_STREAM_END_EVENT) {
done = 1;
}
/* Emit the token. */
if (!yaml_emitter_emit(&emitter, &event))
goto emitter_error;
}
So while in that loop when I attempt to modify the following value
event.data.scalar.value
It must be of type yaml_char_t
yaml_char_t *newHost = "10.132.16.48:6379:1 redis-001";
event.data.scalar.value = newHost;
event.data.scalar.length = sizeof(newHost);
The compiler doesn't complain and the code run by dies with segementation fault. If have seen the examples in the libyaml test directories but nothing is intuitive as far as simply editing a node, at least not to a C newb like myself.
Libyaml expect that the values of each scalar can be removed via free(). So you need to initialize this value with malloc()ed memory:
const char* newHost = "10.132.16.48:6379:1 redis-001";
event.data.scalar.value = (yaml_char_t*)strdup(newHost);
event.data.scalar.length = strlen(newHost);

*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?

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