I am rather saddened by a mistake that I cannot overcome.
For my C programming class at university, I had to implement a parser for GML (Graph Modeling Language) input streams.
If successful, the parser returns the abstract data type to the caller, which is the adjacency matrix as a graph representation.
Well, the parser works flawlessly, there would be no problem that would reduce me to despair over the past few days. There is one function call in the parser, which in turn calls malloc. malloc is called quite often during a scanner that delivers a character to a character to the parser. But the malloc'd memory blocks are ALWAYS freed by calling free () before leaving the scan routine.
But inside the parser there is only one fatal function call, which, in turn, calls a function that uses malloc to reserve 12 bytes of memory (three integer properties) to save the structure. A structure is needed to store information about one edge in a graph (source node, target node, weight).
This call is made two times. for the first time everything is going well. Then, since there can be 1 to n edges according to the gml syntax, the code enters a while loop, where the same pointer is assigned a pointer to the new Edge Struct if there is Edges in the input stream. The first call of the Edge recognition procedure in the loop, which is the second in general (the first of them occurs before entering the loop, see Ma), is constantly interrupted by malloc, returning NULL.
I just have no idea why.
This is not a memory shortage problem, because when I mainall 1000 bytes in the main () function of this program, just for fun, it works fine.
I am using Code :: Blocks and DevCPP as an IDE. In both cases, the program faces the same problem.
Here is my basic parsing procedure:
DirectedGraph Graph(char* sourceString, int*currentPosition){ int sym; int restartPosition = 0; int* backupPosition; char* backupString; int nodeCount = 0; int currentSrc = -1; int currentTgt = -1; int currentWgt = -1; EdgeDescription e; DirectedGraph correctMatrix; MatrixStruct* errorMatrix = NULL; bool isGraphHeader = GraphHdr(sourceString, currentPosition); if(isGraphHeader == true){ bool isNode = Node(sourceString, currentPosition); if(isNode == true){ while(isNode == true){ nodeCount++; restartPosition = *currentPosition; isNode = Node(sourceString, currentPosition); } *currentPosition = restartPosition; e = Edge(sourceString, &restartPosition); restartPosition = 0; currentSrc = e->source; currentTgt = e->target; currentWgt = e->weight; destroyEdge(e); if(currentSrc != -1 && currentTgt != -1 && currentWgt != -1){ correctMatrix = CreateNewGraph(nodeCount); while(currentSrc != -1 && currentTgt != -1 && currentWgt != -1){ if(currentSrc <= nodeCount && currentTgt <= nodeCount){ InsertEdge(correctMatrix, currentSrc, currentTgt, currentWgt); restartPosition = *currentPosition; } e = Edge(sourceString, currentPosition); currentSrc = e->source; currentTgt = e->target; currentWgt = e->weight; } *currentPosition = *currentPosition - 1; sym = GetNextSymbol(sourceString,currentPosition); if(sym == rightBrace){ sym = GetNextSymbol(sourceString, currentPosition); if(sym == eot){ return correctMatrix; } else{ return errorMatrix; } } else{ return errorMatrix; } } else{ return errorMatrix; } } else{ return errorMatrix; } } else{ return errorMatrix; }
}
Here's GetNextSymbol (a scanner that supplies characters to the parser):
int GetNextSymbol(char* sourceString, int* currentPosition){ int symbolCode; int loopCounter = 0; char* currentIdentifier = (char*)malloc(10); char* currentNumber = (char*)malloc(10); int identifierPosition = 0; int numberPos = 0; int numericVal = 0; char currentChar; currentChar = getNextChar(sourceString, currentPosition); while(currentChar == ' ' || currentChar == 11 || currentChar == 10 || currentChar == 13 || currentChar == '\t') { currentChar = getNextChar(sourceString, currentPosition); } if(currentChar == '['){ symbolCode = leftBrace; } else if(currentChar == ']'){ symbolCode = rightBrace; } else if(isdigit(currentChar)){ symbolCode = digit; while(isdigit(currentChar)){ currentNumber[numberPos] = currentChar; currentChar = getNextChar(sourceString, currentPosition); loopCounter++; numberPos++; } currentNumber[numberPos] = '\0'; numericVal = atoi(currentNumber); symbolCode = numericVal; if(isalpha(currentChar)){ *currentPosition = *currentPosition - loopCounter; } else if(currentChar == ']'){ *currentPosition = *currentPosition - loopCounter; } else if(currentChar == '['){ *currentPosition = *currentPosition - loopCounter; } } else if(isalpha(currentChar)){ while(isalpha(currentChar)){ currentIdentifier[identifierPosition] = currentChar; currentChar = getNextChar(sourceString, currentPosition); loopCounter++; identifierPosition++; } currentIdentifier[identifierPosition] = '\0'; symbolCode = recognizeIdentifier(currentIdentifier); if(isdigit(currentChar)){ *currentPosition = *currentPosition - 1; } else if(currentChar == ']'){ *currentPosition = *currentPosition - 1; } else if(currentChar == '['){ *currentPosition = *currentPosition - 1; } } else if(currentChar=='\0'){ symbolCode = eot; } else{ symbolCode = error; } free(currentIdentifier); free(currentNumber); return symbolCode; }
and now a fatal call in the Edge recognition routine. First, the title for the structure
#ifndef GML_EDGE_STRUCT_H_INCLUDED #define GML_EDGE_STRUCT_H_INCLUDED typedef struct EdgeStruct* EdgeObj; typedef struct EdgeStruct { int source; int target; int weight; } EdgeStruct; typedef EdgeObj EdgeDescription; EdgeDescription createNewEdge(int src, int tgt, int wgt); void destroyEdge(EdgeObj); #endif
Implementation
#include "GML_EDGE_STRUCT.h" #include <stdio.h> #include <stdlib.h> EdgeDescription createNewEdge(int source, int target, int weight){ EdgeDescription e; int bytesRequested = sizeof(EdgeStruct); e = malloc(bytesRequested); e->source = source; e->target = target; e->weight = weight; return e; }
I know this is a lot of code;) Just to show that everything that can be freed, I freed.
I ran into my problem over the last two days, of course, also here, when the stack overflows, and there are hundreds of sites, messages, etc. about malloc returning null. They all say basically the same thing: not enough memory (that is, let's call it improbable) or a fragmented heap, so there are no memory blocks of sufficient size.
but: all I'm asking for is 12 (in words: twelve) bytes to store three int properties. which seems too big.
Have I exceeded some internal limits that I don't know about?
Help would be greatly appreciated.
Thanks in advance Roland
EDIT 2012-11-24:
thank you for your responses. but. The problem should be more basic.
because: when I tested other parts of my program (input / output file), etc., which are much less complicated than the parser, and go only one call in depth from main (), I also can not malloc. The file I am reading has approximately 140 bytes. Even when I test an I / O part that is isolated from all other parts, even when I pass them to third-party developers in another project, I do not get any memory from the system. in no way. I restarted the computer, that’s it. absolutely. not. change.
any ideas? at the same time, I spent too many hours on this project, most of which track these errors ... *** - (((