为什么这个void指针的存在会导致Malloc崩溃?

时间:2017-11-04 06:22:31

标签: c pointers struct void libxml2

我有以下小的,不完整的程序,它试图解析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) 我真的很感激任何有关这方面的澄清,因为我对这个很有雾。感谢。

0 个答案:

没有答案