Question

I've run across a rather bizarre exception while running C++ code in my objective-C application. I'm using libxml2 to read an XSD file. I then store the relevant tags as instances of the Tag class in an std::list. I then copy this list into an std::vector using an iterator on the list. However, every now and then some elements of the list aren't copied to the vector. Any help would be greatly appreciated.

 printf("\n length list = %lu, length vector = %lu\n",XSDFile::tagsList.size(), XSDFile::tags.size() );
std::list<Tag>::iterator it = XSDFile::tagsList.begin();
//result: length list = 94, length vector = 0

/*
for(;it!=XSDFile::tagsList.end();++it)
{
    XSDFile::tags.push_back(*it); //BAD_ACCESS code 1  . .  very bizarre . . . . 25
}

 */
std::copy (XSDFile::tagsList.begin(), XSDFile::tagsList.end(), std::back_inserter (XSDFile::tags));

printf("\n Num tags in vector = %lu\n", XSDFile::tags.size());

if (XSDFile::tagsList.size() !=  XSDFile::tags.size())
{
    printf("\n length list = %lu, length vector = %lu\n",XSDFile::tagsList.size(), XSDFile::tags.size() );
    //result: length list = 94, length vector = 83
}
Was it helpful?

Solution

I've found the problem. The memory was corrupted causing the std::list to become corrupted during the parsing of the XSD. I parse the XSD using a function start_element.

xmlSAXHandler handler = {0};
handler.startElement = start_element;

I used malloc guard in xcode to locate the use of freed memory. It pointed to the line:

std::strcpy(message, (char*)name);

So I removed the malloc (actually commented in the code) and it worked. The std::vector now consistently copies all 94 entries of the list. If anyone has an explanation as to why this worked that would be great.

static void start_element(void * ctx, const xmlChar *name, const xmlChar **atts)
{    
// int len = strlen((char*)name);

//    char *message = (char*)malloc(len*sizeof(char));
//    std::strcpy(message, (char*)name);

if (atts != NULL)
{
 //   atts[0] = type
 //   atts[1] = value

 //   len = strlen((char*)atts[1]);
 //   char *firstAttr = (char*)malloc(len*sizeof(char));
 //   std::strcpy(firstAttr, (char*)atts[1]);


     if(strcmp((char*)name, "xs:include")==0)
     {   
         XSDFile xsd;
         xsd.ReadXSDTypes((char*)atts[1]);
     }

     else if(strcmp((char*)name, "xs:element")==0)
     {
         doElement(atts);
     }


     else if(strcmp((char*)name, "xs:sequence")==0)
     {
         //set the default values
         XSDFile::sequenceMin = XSDFile::sequenceMax = 1;

         if (sizeof(atts) == 4)
         {
            if(strcmp((char*)atts[3],"unbounded")==0)
                XSDFile::sequenceMax = -1;

             int i = 0;
             while(atts[i] != NULL)
             {
                 //atts[i] = name
                 //atts[i+i] = value

                 std::string name((char*)atts[i]);
                 std::string value((char*)atts[i+1]);

                 if(name=="minOccurs")
                     XSDFile::sequenceMin = (atoi(value.c_str()));
                 else if(name=="maxOccurs")
                     XSDFile::sequenceMax = (atoi(value.c_str()));

                 i += 2;
             }

         }

     }
}

//free(message);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top