• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

[Gelöst] C - Frage zu Memory Leak mit Char-Pointer bzw. statischem Char-Array

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Hallo,

ich habe gerade etwas Code mit Valkyrie (/Valgrind Frontend) und den "gcc" Compilger Flags "-Ox -g" überprüft und kann gerade nicht nachvollziehen, warum eine bestimmte Code Zeile Memory Leaked.

Folgender Fehler:
4 bytes in 1 blocks are definitely lost in loss record 1 of X

Ich habe eine Struktur mit einem Char-Pointer >char *name<, diese hier, ein Auszug:

[src=c]typedef struct xmlNode {
void *lastAddedElement;
char *name; // <--- um den Namen geht es indirekt!
struct keyValuePair *keyValues;
} xmlNode;[/src]


Jetzt habe ich eine Funktion die einen XML Knoten Zeichenweise in ein statisches Char Array >readData< einliest welches jedoch jeweils nur einen eingelesen Wert enthält den Namen, den Schlüssel bzw. den Wert des Schlüssels.

ReadData wurde, für die ganzen Funktion global, so definiert:
[src=c]char readData[1024];[/src]


Nachdem der Wert eingelesen ist setzte ich an dem "Endpunkt" des Wortes das Null Zeichen und verarbeite das "readData" wie folgt:

Und dabei hebe ich mal die Stelle vor, die ich so nicht verstehe:

[src=c]if (writerPos != 0) {
readData[writerPos] = '\0'; // Hier wird schon explizit gesetzt....

if (!xmlHasName) {
xmlTag->name = malloc(sizeof(char) * (writerPos + 1)); // Diese Zeile wirft das Memory Leak laut Valgrind/Valkyrie
strcpy(xmlTag->name, readData); // bzw. hier.

xmlHasName = true;
} else if (isKey) {
//....
xmlKeyValue->key = malloc(sizeof(char) * (writerPos + 1)); // Wirft kein Leak, auch ohne Umweg
strcpy(xmlKeyValue->key, readData);
//....

isKey = false;
isValue = true;
} else if (isValue) {
xmlKeyValue->value = malloc(sizeof(char) * (writerPos + 1)); // Wirft auch kein Leak, auch ohne den Umweg
strcpy(xmlKeyValue->value, readData);

isValue = false;
}

readData[0] = '\0'; // <-- Ohne diese Stelle bekomme ich ein Memory Leak bei xmlTag->name = malloc....
writerPos = 0;
}[/src]


Und jetzt die Frage/Problem dazu, es wirft ausschließlich der >char* name< mit Malloc und Null-Platzhalter ein Leak, obwohl ich das gleiche mache wie auch für die anderen Werte, Schlüssel/Wert.
Bei letzterem bekomme ich keine Meldung über Speicheraustritt, nur der Name des XML Tags macht komischerweise Probleme* und das ist der erste Wert der gesetzt wird.

Warum bekomme ich diesen nicht, wenn ich explizit >readData[0] = '\0'< setze?
 
Zuletzt bearbeitet:

Brother John

(schein)heilig
Veteran

Registriert
1 Aug. 2013
Beiträge
235
Re: C - Frage zu Memory Leak mit Char-Pointer bzw. statischem Char-Array

Schwierig zu sagen ohne mehr Kontext. Wo/wie stellst du sicher, dass die Pointer, die du mallocst, nicht noch auf allokierten Speicher zeigen? Also wie sind die frees?
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
  • Thread Starter Thread Starter
  • #3
Re: C - Frage zu Memory Leak mit Char-Pointer bzw. statischem Char-Array

Sobald ich >readData[0]< auf >'\0'< setze, verschwindet der Fehler.

Ich habe die Zeile auch schon auskommentiert, bzw. das > strcpy(xmlTag->name, readData) < und dann leaked es nicht mehr. Alles andere funktioniert.
Wenn ich den Namen nicht in den Speicher kopieren lasse wird auch nichts geleaked.

Ich verstehe dann aber nicht wieso ich bei einem statischen Char-Array zusätzlich dieses "zurücksetzen"/"nullen" muß.

Eine Aufräum Routine sieht so aus:

[src=c]
void freeXMLCollection(xmlDataCollection *xmlCollection) {

xmlNode *xmlTag = NULL;

for (unsigned int i = 0; i < xmlCollection->count; ++i) {
xmlTag = &xmlCollection->nodes;

for (unsigned int j = 0; j < xmlTag->keyValuePairs; ++j) {
free(xmlTag->keyValues[j].key);
free(xmlTag->keyValues[j].value);
}

for (unsigned int j = 0; j < xmlTag->wordCount; ++j) {
free(xmlTag->words[j].data);
}

for (unsigned int j = 0; j < xmlTag->wTagCount; ++j) {
freeXMLCollectionTag(&xmlTag->wikiTags[j]);
}

free(xmlTag->name); // Wird hier freigegeben!
free(xmlTag->keyValues);
free(xmlTag->words);
free(xmlTag->entities);
free(xmlTag->wikiTags);
}

free(xmlCollection->nodes);
free(xmlCollection->openNodes);

if (debug) {
printf("[DEBUG] Successfully cleaned up xmlCollection...\n");
}

return;
}[/src]
 
Zuletzt bearbeitet:

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
  • Thread Starter Thread Starter
  • #4
Re: C - Frage zu Memory Leak mit Char-Pointer bzw. statischem Char-Array

Ich stehe gerade auf dem Schlauch, wie so immer bei diesen Problemen... nun ja.

Erstmal was genau mir Valkyrie/Valgrind so sagen will, wenn ich mit Memcheck checke:

Bildschirmfoto von »2016-07-22 21-03-06«.png


und

Bildschirmfoto von »2016-07-22 21-04-00«.png



Sorry falls das jetzt schon wieder zig Zeilen Code sind, aber ich glaube ohne wird nicht ersichtlich was falsch läuft...
und ich kann den Fehler einfach so nicht nachvollziehen... - wäre schön wenn jemand mir einen Tip geben könnte wo ich suchen muß.

Vielleicht verstehe ich auch nicht ganz die Ausgabe in Valkyrie von Valgrind/Memcheck...

Die Routine, und nur diese scheint ja Probleme zu machen, sieht so aus:

[src=c]int parseXMLNode(const int xmlTagStart, const unsigned int lineLength, const unsigned int currentLine, const char *line, xmlDataCollection *xmlCollection) {
xmlCollection->nodes = (xmlNode*) realloc(xmlCollection->nodes, sizeof(xmlNode) * (xmlCollection->count + 1));
xmlNode *xmlTag = &xmlCollection->nodes[xmlCollection->count];

/*
typedef struct xmlNode {
bool isClosed;
bool isDataNode;
unsigned short indent;
short lastAddedType; // 0 WORD, 1 WIKITAG, 2 ENTITY
unsigned int keyValuePairs;
unsigned int wordCount;
unsigned int entityCount;
unsigned int wTagCount;
unsigned int start;
unsigned int end;
unsigned int lineCount;
void *lastAddedElement;
char *name;
struct keyValuePair *keyValues;
struct word *words;
struct entity *entities;
struct wikiTag *wikiTags;
} xmlNode;
*/

xmlTag->isClosed = false;
xmlTag->isDataNode = false;
xmlTag->indent = xmlTagStart;
xmlTag->lastAddedType = -1; // 0 WORD, 1 WIKITAG, 2 ENTITY
xmlTag->keyValuePairs = 0;
xmlTag->wordCount = 0;
xmlTag->entityCount = 0;
xmlTag->wTagCount = 0;
xmlTag->start = currentLine;
xmlTag->end = 0;
xmlTag->lineCount = 0;
xmlTag->lastAddedElement = NULL;
xmlTag->name = NULL;
xmlTag->keyValues = NULL;
xmlTag->words = NULL;
xmlTag->entities = NULL;
xmlTag->wikiTags = NULL;


// Routine variables
unsigned int readerPos = xmlTagStart+1;

char readIn = '\0';
char readData[xmlNodeReaderBuffer] = "\0";
int writerPos = 0;

bool xmlHasName = false;
bool isKey = false;
bool isValue = false;

bool nodeClosed = false;
keyValuePair *xmlKeyValue = NULL;


// Identify the xmlTag name and key and value pairs
while (line[readerPos] != '>') {
while (line[readerPos] != '>') {
readIn = line[readerPos];

if (!isValue) {
if (readIn == ' ') {
++readerPos;
break;
} else if (readIn == '=') {
readerPos += 2;
isKey = true;
break;
} else if (readIn == '/') {
xmlTag->isClosed = true;
xmlTag->end = currentLine;
readerPos++;
continue;
}
} else if (readIn == '"') {
++readerPos;
break;
}

readData[writerPos] = readIn;
++writerPos;
++readerPos;
continue;
}

if (writerPos != 0) {
readData[writerPos] = '\0';

if (!xmlHasName) {
xmlTag->name = malloc(sizeof(char) * (writerPos + 1));
strcpy(xmlTag->name, readData);

xmlHasName = true;
} else if (isKey) {
xmlTag->keyValues = (keyValuePair*) realloc(xmlTag->keyValues, sizeof(keyValuePair) * (xmlTag->keyValuePairs + 1) );

xmlKeyValue = &xmlTag->keyValues[xmlTag->keyValuePairs];
xmlKeyValue->value = NULL;

xmlKeyValue->key = malloc(sizeof(char) * (writerPos + 1));
strcpy(xmlKeyValue->key, readData);

++xmlTag->keyValuePairs;

isKey = false;
isValue = true;
} else if (isValue) {
xmlKeyValue->value = malloc(sizeof(char) * (writerPos + 1));
strcpy(xmlKeyValue->value, readData);

isValue = false;
}

writerPos = 0;
readData[0] = '\0';
}

}

//--------------------------------------------------------------------------
// NOTE: Does adjust so we know if data follows the xmlTag
++readerPos;

char *endPointer = strrchr(line, '<');
unsigned int xmlEnd = endPointer != NULL ? endPointer - line : 0;

if (readerPos > xmlEnd) {
xmlEnd = lineLength-1;

if (debug && beVerbose) {
printf("\n\n[DEBUG] RP: %8d | END: %8d | LINELENGTH: %d | NAME: %s\n", readerPos, xmlEnd, lineLength, xmlTag->name);
}
}

//--------------------------------------------------------------------------

if (xmlHasName) {
if (!xmlTag->isClosed) {
xmlCollection->openNodes = (unsigned int*) realloc(xmlCollection->openNodes, sizeof(unsigned int) * (xmlCollection->openNodeCount + 1));
xmlCollection->openNodes[xmlCollection->openNodeCount] = xmlCollection->count;
++xmlCollection->openNodeCount;
} else {
nodeClosed = false;
printf("%s\n", readData);
for (int i = xmlCollection->openNodeCount - 1; i != -1; --i) {
xmlNode *openXMLNode = &xmlCollection->nodes[xmlCollection->openNodes];
if (strcmp(xmlTag->name, openXMLNode->name) == 0) {
openXMLNode->isClosed = true;
openXMLNode->end = currentLine;

if (i < (xmlCollection->openNodeCount-1)) {
memmove(&xmlCollection->openNodes, &xmlCollection->openNodes[i+1], (xmlCollection->openNodeCount-(i+1)) * sizeof(unsigned int));

xmlCollection->openNodes = (unsigned int*) realloc(xmlCollection->openNodes, sizeof(unsigned int) * xmlCollection->openNodeCount);
--xmlCollection->openNodeCount;
}

if (beVerbose || debug) {
printf("[STATUS] | LINE: %8d | %sNODE CLOSED: '%s'\n", currentLine, openXMLNode->isDataNode ? "DATA " : "", openXMLNode->name);
}

nodeClosed = true;

break;
}
}

if (nodeClosed) {
return 0;
}

}

if (beVerbose || debug) {
printf("\n\n[STATUS] | LINE: %8d | %s%sNODE ADDED: '%s'\n", currentLine, xmlTag->isClosed ? "CLOSED " : "", readerPos < xmlEnd ? "DATA " : "", xmlTag->name);
for (unsigned int i = 0; i < xmlTag->keyValuePairs; ++i) {
printf("[STATUS] | KEYVALUE: '%s' > '%s'\n", xmlTag->keyValues.key, xmlTag->keyValues.value);
}
}

++xmlCollection->count;

} else {
return 0;
}

// Start process the data of the XML tag

if (readerPos < xmlEnd) {
xmlTag->isDataNode = true;
parseXMLData(readerPos, xmlEnd, currentLine, line, xmlTag);
}

return 1;
}[/src]


Die zwei die Aufräumen habe ich nochmal angepasst, sollten aber theoretissch allen Speicher freigeben:

[src=c]void freeXMLCollection(xmlDataCollection *xmlCollection) {

xmlNode *xmlTag = NULL;

for (unsigned int i = 0; i < xmlCollection->count; ++i) {
xmlTag = &xmlCollection->nodes;

for (unsigned int j = 0; j < xmlTag->keyValuePairs; ++j) {
free(xmlTag->keyValues[j].key);
free(xmlTag->keyValues[j].value);
}

for (unsigned int j = 0; j < xmlTag->wordCount; ++j) {
free(xmlTag->words[j].data);
}

for (unsigned int j = 0; j < xmlTag->wTagCount; ++j) {
freeXMLCollectionTag(&xmlTag->wikiTags[j]);
}

free(xmlTag->name);
free(xmlTag->keyValues);
free(xmlTag->words);
free(xmlTag->entities);
free(xmlTag->wikiTags);
}

free(xmlCollection->nodes);
free(xmlCollection->openNodes);

if (debug) {
printf("[DEBUG] Successfully cleaned up xmlCollection...\n");
}

return;
}

void freeXMLCollectionTag(wikiTag *wTag) {
/*
typedef struct wikiTag {
bool hasParentFormat;
short formatType;
unsigned short tagType;
unsigned short formatGroup;
unsigned short preSpacesCount;
unsigned short spacesCount;
unsigned int position;
unsigned int wordCount;
unsigned int wTagCount;
unsigned int entityCount;
char *target;
struct word *pipedWords;
struct wikiTag *pipedTags;
struct entity *pipedEntities;
} wikiTag;
*/

for (unsigned int i = 0; i < wTag->wordCount; ++i) {
free(wTag->pipedWords.data);
}

for (unsigned int i = 0; i < wTag->wTagCount; ++i) {
freeXMLCollectionTag(&wTag->pipedTags);
}

free(wTag->target);
free(wTag->pipedWords);
free(wTag->pipedTags);
free(wTag->pipedEntities);

return;
}[/src]
 

Brother John

(schein)heilig
Veteran

Registriert
1 Aug. 2013
Beiträge
235
Re: C - Frage zu Memory Leak mit Char-Pointer bzw. statischem Char-Array

Ich seh das Speicherproblem auch nicht. Mag an der mangelnden Erfahrung mit Valgrind liegen. Was mir aufgefallen ist:

In parseXMLNode() hast du eine doppelte while-Schleife:
Code:
      while (line[readerPos] != '>') {
        while (line[readerPos] != '>') {
Die äußere kannst du dir sparen bzw. falls nötig in ein if umwandeln. Sie wird nie öfter als 1x durchlaufen, weil readerPos nach der inneren Schleife nicht mehr verändert wird.

In freeXMLCollection():
Code:
      free(xmlCollection->nodes);
      free(xmlCollection->openNodes);
Alles in openNodes ist tatsächlich non-owning und wurde schon bei der Schleife über die Nodes weggeräumt?
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
  • Thread Starter Thread Starter
  • #6
Re: C - Frage zu Memory Leak mit Char-Pointer bzw. statischem Char-Array

Danke für den Hinweis mit der doppelten While Schleife, die war in der Tat unnötig. :) Ich bin mir auch gerade nicht ganz sicher warum ich die dort drin hatte. ;)

*Anmerkung/Nachtrag - die zweite While Schleife war wohl doch nötig... damit alle Schlüssel korrekt eingelesen werden. ;)


OpenNodes ist vom Typ >unsigned int*< (also ein "unsigned int"-Array) und beinhaltet Knoten die geöffnet, aber nicht sofort in der selben Zeile gleich wieder geschlossen werden.

Ist ein Teil der xmlDataCollection, die sich wie folgt definiert:
[src=c]typedef struct xmlDataCollection {
unsigned int count;
unsigned int openNodeCount;
struct xmlNode *nodes;
unsigned int *openNodes;
} xmlDataCollection;[/src]

Dazu gehört auch die >xmlCollection< die daraus definiert wird.

Denke das klärt deinen Hinweis auf. :)

Aber danke für das Feedback. :T
 
Zuletzt bearbeitet:

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
  • Thread Starter Thread Starter
  • #7
Re: C - Frage zu Memory Leak mit Char-Pointer bzw. statischem Char-Array

@Brother John, du hast mir gerade DEN richtigen Hinweis gegeben.... vielleicht ohne es zu wissen. :D

Ich habe doch in dem ersten Code-Part, die Zeilen 173 bis 175, folgendes:
[src=c] if (nodeClosed) {
return 0;
}[/src]

Und danach erst, also nach diesem möglichen Return aus der Funktion, in Zeile 186, das hier:
[src=c] ++xmlCollection->count;[/src]

Das Problem dabei war also, ich habe, obwohl eine xmlNode hinzugefügt wurde, nie den Counter für die Anzahl erhöht wenn diese geschlossen war...

Jetzt bekomme ich keine Memory Leaks mehr!




Bzw. sieht der Funktion jetzt so aus:

[src=c] int parseXMLNode(const int xmlTagStart, const unsigned int lineLength, const unsigned int currentLine, const char *line, xmlDataCollection *xmlCollection) {
xmlCollection->nodes = (xmlNode*) realloc(xmlCollection->nodes, sizeof(xmlNode) * (xmlCollection->count + 1));
xmlNode *xmlTag = &xmlCollection->nodes[xmlCollection->count];

/*
typedef struct xmlNode {
bool isClosed;
bool isDataNode;
unsigned short indent;
short lastAddedType; // 0 WORD, 1 WIKITAG, 2 ENTITY
unsigned int keyValuePairs;
unsigned int wordCount;
unsigned int entityCount;
unsigned int wTagCount;
unsigned int start;
unsigned int end;
unsigned int lineCount;
void *lastAddedElement;
char *name;
struct keyValuePair *keyValues;
struct word *words;
struct entity *entities;
struct wikiTag *wikiTags;
} xmlNode;
*/

xmlTag->isClosed = false;
xmlTag->isDataNode = false;
xmlTag->indent = xmlTagStart;
xmlTag->lastAddedType = -1; // 0 WORD, 1 WIKITAG, 2 ENTITY
xmlTag->keyValuePairs = 0;
xmlTag->wordCount = 0;
xmlTag->entityCount = 0;
xmlTag->wTagCount = 0;
xmlTag->start = currentLine;
xmlTag->end = 0;
xmlTag->lineCount = 0;
xmlTag->lastAddedElement = NULL;
xmlTag->name = NULL;
xmlTag->keyValues = NULL;
xmlTag->words = NULL;
xmlTag->entities = NULL;
xmlTag->wikiTags = NULL;


// Routine variables
unsigned int readerPos = xmlTagStart+1;

char readIn = '\0';
char readData[xmlNodeReaderBuffer];
int writerPos = 0;

bool xmlHasName = false;
bool isKey = false;
bool isValue = false;

bool nodeClosed = false;
keyValuePair *xmlKeyValue = NULL;


// Identify the xmlTag name and key and value pairs
while (line[readerPos] != '>') {
readIn = line[readerPos];

if (!isValue) {
if (readIn == ' ') {
++readerPos;
break;
} else if (readIn == '=') {
readerPos += 2;
isKey = true;
break;
} else if (readIn == '/') {
xmlTag->isClosed = true;
xmlTag->end = currentLine;
readerPos++;
continue;
}
} else if (readIn == '"') {
++readerPos;
break;
}

readData[writerPos] = readIn;
++writerPos;
++readerPos;
continue;
}

if (writerPos != 0) {

readData[writerPos] = '\0';
if (!xmlHasName) {
xmlTag->name = malloc(sizeof(char) * (writerPos + 1));
strcpy(xmlTag->name, readData);

xmlHasName = true;
} else if (isKey) {
xmlTag->keyValues = (keyValuePair*) realloc(xmlTag->keyValues, sizeof(keyValuePair) * (xmlTag->keyValuePairs + 1) );

xmlKeyValue = &xmlTag->keyValues[xmlTag->keyValuePairs];
xmlKeyValue->value = NULL;

xmlKeyValue->key = malloc(sizeof(char) * (writerPos + 1));
strcpy(xmlKeyValue->key, readData);

++xmlTag->keyValuePairs;

isKey = false;
isValue = true;
} else if (isValue) {
xmlKeyValue->value = malloc(sizeof(char) * (writerPos + 1));
strcpy(xmlKeyValue->value, readData);

isValue = false;
}

writerPos = 0;
}

//--------------------------------------------------------------------------
// NOTE: Does adjust so we know if data follows the xmlTag
++readerPos;

char *endPointer = strrchr(line, '<');
unsigned int xmlEnd = endPointer != NULL ? endPointer - line : 0;

if (readerPos > xmlEnd) {
xmlEnd = lineLength-1;

if (debug && beVerbose) {
printf("\n\n[DEBUG] RP: %8d | END: %8d | LINELENGTH: %d | NAME: %s\n", readerPos, xmlEnd, lineLength, xmlTag->name);
}
}

//--------------------------------------------------------------------------

if (xmlHasName) {
++xmlCollection->count; // Das haette von anbeginn hier schon erhoeht werden muessen, so ists richtig!

if (!xmlTag->isClosed) {
xmlCollection->openNodes = (unsigned int*) realloc(xmlCollection->openNodes, sizeof(unsigned int) * (xmlCollection->openNodeCount + 1));
xmlCollection->openNodes[xmlCollection->openNodeCount] = xmlCollection->count - 1;
++xmlCollection->openNodeCount;
} else {
nodeClosed = false;
//printf("%s\n", readData);
for (int i = xmlCollection->openNodeCount - 1; i != -1; --i) {
xmlNode *openXMLNode = &xmlCollection->nodes[xmlCollection->openNodes];
if (strcmp(xmlTag->name, openXMLNode->name) == 0) {
openXMLNode->isClosed = true;
openXMLNode->end = currentLine;

if (i < (xmlCollection->openNodeCount-1)) {
memmove(&xmlCollection->openNodes, &xmlCollection->openNodes[i+1], (xmlCollection->openNodeCount-(i+1)) * sizeof(unsigned int));

xmlCollection->openNodes = (unsigned int*) realloc(xmlCollection->openNodes, sizeof(unsigned int) * xmlCollection->openNodeCount);
--xmlCollection->openNodeCount;
}

if (beVerbose || debug) {
printf("[STATUS] | LINE: %8d | %sNODE CLOSED: '%s'\n", currentLine, openXMLNode->isDataNode ? "DATA " : "", openXMLNode->name);
}

nodeClosed = true;

break;
}
}

if (nodeClosed)
return 1;
}

if (beVerbose || debug) {
printf("\n\n[STATUS] | LINE: %8d | %s%sNODE ADDED: '%s'\n", currentLine, xmlTag->isClosed ? "CLOSED " : "", readerPos < xmlEnd ? "DATA " : "", xmlTag->name);
for (unsigned int i = 0; i < xmlTag->keyValuePairs; ++i) {
printf("[STATUS] | KEYVALUE: '%s' > '%s'\n", xmlTag->keyValues.key, xmlTag->keyValues.value);
}
}
} else {
return 0;
}

// Start process the data of the XML tag

if (readerPos < xmlEnd) {
xmlTag->isDataNode = true;
parseXMLData(readerPos, xmlEnd, currentLine, line, xmlTag);
}

return 1;
}[/src]
 
Zuletzt bearbeitet:
Oben