我有以下小的,不完整的程序,它试图解析XML文件中的数据。某些数据的性质将提前未知,因此我将其中一些void指针合并到一个结构中。当我在这里运行程序时,我遇到了一些奇怪的运行时错误。
您可能会注意到我的链接列表中存在一些错误;我不是要求你调试它(虽然如果它让你感到困扰,你会感到自由。我正在恳求有人告诉我为什么会崩溃。我对原因一无所知我坦率地害怕继续调试它直到这是说明。
#include <stdio.h>
#include <string.h>
#include <libxml/xmlreader.h>
typedef struct attributes{
xmlChar *name;
void *data;
struct attributes *next;
};
typedef struct entity{
char *reference;
void *data;
struct attributes *my_attribs;
struct entity *next;
};
typedef struct world_list{
void *data;
struct entity *entity_list;
struct world_list *next;
};
int main (int argc, char *argv[])
{
xmlDocPtr doc;
xmlNodePtr cur;
printf("---WARNING---\n Weird things will happen to your world if you do not use a properly formatted XML document with NO SPACES (tabs only) in between texts! \n\nThis may be fixed in future versions.\n---WARNING---\n\n");
getchar();
xmlNodePtr iterate;
doc = xmlParseFile("./simple2.xml");
if (doc== NULL) {
printf("Document not parsed");
return 1;
}
cur = xmlDocGetRootElement(doc);
if (cur == NULL) {
fprintf(stderr,"empty document\n");
xmlFreeDoc(doc);
return 2;
}
//cur->name: The node that we are in.
if (xmlStrcmp(cur->name, (const xmlChar *) "world")) {
fprintf(stderr,"document of the wrong type, root node != story");
xmlFreeDoc(doc);
return 3;
}
printf("cur->name: %s\n",cur->name);
iterate=cur->children;
//iterate=iterate->children;
if (iterate==NULL) {
printf("what the hell");
}
xmlNodePtr contents;
struct world_list world; //This line of code creates the world.
struct entity *entity_list;
struct entity *entity_current;
entity_list=NULL;
struct attributes *attribute_list=NULL;
//world.entity_list=entity_list;
while (iterate!=NULL){
// if (xmlStrcmp(iterate->name, (const xmlChar *) "object")){
xmlChar *key;
key = xmlNodeListGetString(doc, iterate->xmlChildrenNode, 1);
if (key==NULL) {xmlFree(key);iterate=iterate->next;continue;}
printf("|name: %s, getstring: %s|\n",iterate->name,key);
xmlFree(key);
if (!xmlStrcmp(iterate->name, (const xmlChar *) "object")) { //WHY does this need to be inverted !?!?
if (entity_list == NULL){
printf("entity_list initilized start");
entity_list=malloc(sizeof(entity_list));
printf("entity_list initilized done");
entity_list->next=NULL;
entity_current=entity_list;
} else
{
printf("list NOT init");
entity_current->next=malloc(sizeof(entity_list));
entity_current=entity_current->next;
}
contents=iterate->children;
xmlChar *key2;
while (contents != NULL) {
key2 = xmlNodeListGetString(doc, contents->xmlChildrenNode, 1);
if (key2==NULL) {xmlFree(key2);contents=contents->next;continue;}
if (attribute_list==NULL) {
entity_current->my_attribs = malloc(sizeof(attribute_list));
attribute_list = entity_current->my_attribs;
} else {
attribute_list->next = malloc(sizeof(attribute_list));
attribute_list=attribute_list->next;
}
attribute_list->name=malloc(sizeof(xmlChar)*xmlStrlen(key2));
printf("the key being added is %s", key2);
*attribute_list->name = *key2;
attribute_list->next=NULL;
entity_current->next=NULL;
printf("Subchild: |name: %s, getstring: %s|\n",contents->name,key2);
xmlFree(key2);
contents=contents->next;
}
attribute_list=NULL; //If you don't do this the attributes of one object will be added on the list of another object's attributes; good luck with that.
}
iterate=iterate->next;
}
//entity_current->next=NULL;
entity_current=entity_list;
if (entity_current == NULL) {printf("uh-oh."); return 4;}
int track=0;
while (entity_current!= NULL){
printf("Properties for: %i\n",track++);
printf("-------\n");
attribute_list=entity_current->my_attribs;
while (attribute_list != NULL) {
printf("item %s\n",attribute_list->name);
attribute_list=attribute_list->next;
}
printf("-------\n");
entity_current=entity_current->next;
}
//Keep iterating EVERY OTHER ->next will be "text"
//Regardless of whether or not you are in "child mode"
return 0;
}
我收到以下错误:
Error in `./statact': malloc(): memory corruption (fast): 0x000000000068eda0
entity_list initilized startentity_list initilized doneAborted
(你会在这里看到printfs。)
然而,有些事情很奇怪。我发现只是通过注释掉在结构中定义void指针的代码行...... 程序不会崩溃。
还有另一种方法可以让它在不崩溃的情况下执行:以行if (entity_list == NULL){
开头的if-else块可以移动到循环的开头以下,立即在它下面while (contents != NULL) {
并且它似乎也没有崩溃(虽然我目前的意图或多或少等于逻辑错误)。
我的其他信息是:
-Debian稳定
- 当我的程序启动时,它会打印到控制台消息./statact: /usr/local/lib/libxml2.so.2: no version information available (required by ./statact)
我真的很感激任何有关这方面的澄清,因为我对这个很有雾。感谢。