2013-04-08 109 views
3

我一直在使用xmpp框架通過Robbiehanson爲mac.While檢查工具在mac中 工具,我觀察到XMPPParser.m類中的泄漏(大約64字節),它逐漸增加時間。下面給出了泄漏的代碼。xmpp框架內存泄漏通過Robbiehanson

attrNs = xmlNewNs(NULL,NULL,nodePrefix); CHECK_FOR_NULL(attrNs);

請提供針對此問題的解決方案...

包含該代碼的方法粘貼下面以供參考:

static void xmpp_xmlStartElement(void *ctx, const xmlChar *nodeName, 
const xmlChar *nodePrefix, 
const xmlChar *nodeUri, 
int nb_namespaces, 
const xmlChar **namespaces, 
int nb_attributes, 
int nb_defaulted, 
const xmlChar **attributes) 
{ 

NSLog(@"IN xmppStartElement"); 
int i, j; 
xmlNsPtr lastAddedNs = NULL; 

xmlParserCtxt *ctxt = (xmlParserCtxt *)ctx; 

// We store the parent node in the context's node pointer. 
// We keep this updated by "pushing" the node in the startElement method, 
// and "popping" the node in the endElement method. 
xmlNodePtr parent = ctxt->node; 

// Create the node 
xmlNodePtr newNode = xmlNewDocNode(ctxt->myDoc, NULL, nodeName, NULL); 
CHECK_FOR_NULL(newNode); 

// Add the node to the tree 
if(parent == NULL) 
{ 
    // Root node 
    xmlAddChild((xmlNodePtr)ctxt->myDoc, newNode); 
} 
else 
{ 
    xmlAddChild(parent, newNode); 
} 

// Process the namespaces 
for (i = 0, j = 0; j < nb_namespaces; j++) 
{ 
    // Extract namespace prefix and uri 
    const xmlChar *nsPrefix = namespaces[i++]; 
    const xmlChar *nsUri = namespaces[i++]; 

    // Create the namespace 
    xmlNsPtr newNs = xmlNewNs(NULL, nsUri, nsPrefix); 
    CHECK_FOR_NULL(newNs); 

    // Add namespace to node. 
    // Each node has a linked list of nodes (in the nsDef variable). 
    // The linked list is forward only. 
    // In other words, each ns has a next, but not a prev pointer. 

    if (newNode->nsDef == NULL) 
    { 
     newNode->nsDef = lastAddedNs = newNs; 
    } 
    else 
    { 
     lastAddedNs->next = newNs; 
     lastAddedNs = newNs; 
    } 

    // Is this the namespace for the node? 

    if (nodeUri && (nodePrefix == nsPrefix)) 
    { 
     // Ex 1: node == <stream:stream xmlns:stream="url"> && newNs == stream:url 
     // Ex 2: node == <starttls xmlns="url">    && newNs == null:url 

     newNode->ns = newNs; 
    } 
} 

// Search for the node's namespace if it wasn't already found 
if ((nodeUri) && (newNode->ns == NULL)) 
{ 
    newNode->ns = xmpp_xmlSearchNs(ctxt->myDoc, newNode, nodePrefix); 

    if (newNode->ns == NULL) 
    { 
     // We use href==NULL in the case of an element creation where the namespace was not defined. 
     // 
     // We do NOT use xmlNewNs(newNode, nodeUri, nodePrefix) because that method doesn't properly add 
     // the namespace to BOTH nsDef and ns. 

     xmlNsPtr newNs = xmlNewNs(NULL, nodeUri, nodePrefix); 
     CHECK_FOR_NULL(newNs); 

     if (newNode->nsDef == NULL) 
     { 
      newNode->nsDef = lastAddedNs = newNs; 
     } 
     else 
     { 
      lastAddedNs->next = newNs; 
      lastAddedNs = newNs; 
     } 

     newNode->ns = newNs; 
    } 
} 

// Process all the attributes 
for (i = 0, j = 0; j < nb_attributes; j++) 
{ 
    const xmlChar *attrName = attributes[i++]; 
    const xmlChar *attrPrefix = attributes[i++]; 
    const xmlChar *attrUri = attributes[i++]; 
    const xmlChar *valueBegin = attributes[i++]; 
    const xmlChar *valueEnd = attributes[i++]; 

    // The attribute value might contain character references which need to be decoded. 
    // 
    // "Franks &#38; Beans" -> "Franks & Beans" 

    xmlChar *value = xmlStringLenDecodeEntities(ctxt,     // the parser context 
               valueBegin,    // the input string 
              (int)(valueEnd - valueBegin), // the input string length 
               (XML_SUBSTITUTE_REF),  // what to substitue 
               0, 0, 0);    // end markers, 0 if none 
    CHECK_FOR_NULL(value); 

    if ((attrPrefix == NULL) && (attrUri == NULL)) 
    { 
     // Normal attribute - no associated namespace 
     xmlAttrPtr newAttr = xmlNewProp(newNode, attrName, value); 
     CHECK_FOR_NULL(newAttr); 
    } 
    else 
    { 
     // Find the namespace for the attribute 
     xmlNsPtr attrNs = xmpp_xmlSearchNs(ctxt->myDoc, newNode, attrPrefix); 

     if (attrNs != NULL) 
     { 
      xmlAttrPtr newAttr = xmlNewNsProp(newNode, attrNs, attrName, value); 
      CHECK_FOR_NULL(newAttr); 
     } 
     else 
     { 
      **attrNs = xmlNewNs(NULL, NULL, nodePrefix); 
      CHECK_FOR_NULL(attrNs);** 

      xmlAttrPtr newAttr = xmlNewNsProp(newNode, attrNs, attrName, value); 
      CHECK_FOR_NULL(newAttr); 

     } 
    } 

    xmlFree(value); 

} 

// Update our parent node pointer 
ctxt->node = newNode; 

// Invoke delegate methods if needed 
xmpp_postStartElement(ctxt); 

} 
+0

你有沒有用@autoreleasepool試過。它會在一定程度上造成泄漏? sdk本身是否包含泄漏? – Ganapathy 2013-04-08 10:40:10

+0

這段代碼是用c語言編寫的。所以不能使用@ autoreleasepool。據我所知,代碼片段attrNs = xmlNewNs(NULL,NULL,nodePrefix);導致泄漏。它的內​​存被分配,永遠不會釋放。 – sreenath 2013-04-08 11:10:14

回答

3

嘗試用最後CHECK_FOR_NULL(newAttr);下方添加xmlFreeNs(attrNs);

+0

我試過添加xmlFreeNs(attrNs);但應用程序崩潰, 任何適當的答案會有所幫助。 – 2017-08-31 10:04:31