我正在使用Ben Reeves' HTML parser来解析带有一些HTML标记的文本。它将每个节点表示为一个HTMLNode对象,该对象只有libxml2中的一个xmlNode *类型的ivar。 xmlNode是一个看起来像这样的结构:

struct _xmlNode {
void           *_private;   /* application data */
xmlElementType   type;  /* type number, must be second ! */
const xmlChar   *name;      /* the name of the node, or the entity */
struct _xmlNode *children;  /* parent->childs link */
struct _xmlNode *last;  /* last child link */
struct _xmlNode *parent;    /* child->parent link */
struct _xmlNode *next;  /* next sibling link  */
struct _xmlNode *prev;  /* previous sibling link  */
struct _xmlDoc  *doc;   /* the containing document */

/* End of common part */
xmlNs           *ns;        /* pointer to the associated namespace */
xmlChar         *content;   /* the content */
struct _xmlAttr *properties;/* properties list */
xmlNs           *nsDef;     /* namespace definitions on this node */
void            *psvi;  /* for type/PSVI informations */
unsigned short   line;  /* line number */
unsigned short   extra; /* extra data for XPath/XSLT */


};

我有一个方法,它接受一个字符串,将其包装到HTMLNode中并返回该节点:

- (HTMLNode*)nodeFromString:(NSString*)string
{
    /* Creates parser which wraps string in <doc><html><body> tags */

    HTMLParser *parser = [[HTMLParser alloc] initWithString:string error:nil];

    /* Get contents of <body> tag and return it to parse later */

    HTMLNode *body = [parser body];
    return body;
}


在此方法内使用此HTMLNode很好。但是,如果我尝试在代码的其他位置使用此节点,则会得到非常奇怪的结果。 xmlNode结构中的大多数变量都指向内存中的一些随机位置。

这是HTMLNode的调试输出在nodeFromString方法内部的样子:

body    HTMLNode *  0x7faaf96a3240  0x00007faaf96a3240
_node   xmlNode *   0x7faaf96b7ec0  0x00007faaf96b7ec0
    _private    void *  NULL    0x0000000000000000
    type    xmlElementType  XML_ELEMENT_NODE    XML_ELEMENT_NODE
    name    const xmlChar * "body"  0x00007faaf9693df0
    children    _xmlNode *  0x7faaf96b7fd0  0x00007faaf96b7fd0
        _private    void *  NULL    0x0000000000000000
        type    xmlElementType  XML_ELEMENT_NODE    XML_ELEMENT_NODE
        name    const xmlChar * "p" 0x00007faaf9678470
        children    _xmlNode *  0x7faaf96b80e0  0x00007faaf96b80e0
            _private    void *  NULL    0x0000000000000000
            type    xmlElementType  XML_TEXT_NODE   XML_TEXT_NODE
            name    const xmlChar * "text"  0x0000000100e31304
            children    _xmlNode *  NULL    0x0000000000000000
            content xmlChar *   "My content string" 0x00007faafa910200


这是从此方法返回并在其他地方使用的同一HTMLNode对象的调试输出:

body    HTMLNode *  0x7faaf96a3240  0x00007faaf96a3240
_node   xmlNode *   0x7faaf96b7ec0  0x00007faaf96b7ec0
    _private    void *  0x900007faaf96b7db  0x900007faaf96b7db
    type    xmlElementType  -1349076995 -1349076995
    name    const xmlChar * 0x7faaf969000a  0x00007faaf969000a
    children    _xmlNode *  0x7faaf96b7fd0  0x00007faaf96b7fd0
        _private    void *  0x600007faaf96b7ec  0x600007faaf96b7ec
        type    xmlElementType  -1349076978 -1349076978
        name    const xmlChar * ""  0x00007faaf967000a
        children    _xmlNode *  0x7faaf96b80e0  0x00007faaf96b80e0
            _private    void *  0x700007faaf96b7fd  0x700007faaf96b7fd
            type    xmlElementType  -1349076961 -1349076961
            name    const xmlChar * "XPathEvalExpression: %d object left on the stack\n"    0x0000000100e3000a
            children    _xmlNode *  NULL    0x0000000000000000
            content xmlChar *   "My content string" 0x00007faafa910200


为什么xmlNode ivar的内存损坏?我应该怎么做才能避免这种情况(我真的不想在一个方法中解析整个字符串)?

重现此问题的简单示例项目可以在here中找到。

最佳答案

我认为这是解析器的错误。 Xml层次结构由HTMLParser对象释放。

关于objective-c - objective-c 中struct ivar的奇怪内存行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26673858/

10-10 07:04