2014-06-10 114 views
0

我正在创建一个使用RapidXML从xml文件读取数据的C++程序。由于RapidXML分配指向用于访问它的xml内容的指针,因此只要文件的内容在进一步的步骤中被解析,它就需要文件的内容。将char数组缓冲区动态分配给传递的char的C++函数*

所以我有几个文件解析成功,但在每个文件解析的开始,我总是有所有的ifstream和分配继续。我提出了创建一个函数来获取文件路径,指向xml_document <>实例等等并返回xml文件的根节点的想法。然后我意识到,我可能会遇到动态分配的char数组中包含要解析并稍后指向的xml内容的范围问题。

然后,我尝试了以下技术,我分配了一个char *,xml_document和xml_node并调用该函数来检索根节点。

功能:

bool readXML(const char * path, char * buffer, xml_document<> * doc, const char * rootNodeName, xml_node<> * root_node){ 
// Open file 
    ifstream file(path, ios::in|ios::binary); 
    if (!file.is_open()){ err(ERR_FILE_NOTFOUND,path); return 0; } 
// Get length 
    file.seekg(0,file.end); 
    int length = file.tellg(); 
    file.seekg(0,file.beg); 
// Allocate buffer 
    buffer = new char [length+1]; 
    file.read(buffer,length); 
    buffer[length] = '\0'; 
    file.close(); 
// Parse 
    doc->parse<0>(buffer); 

// Get root node 
    root_node = doc->first_node(rootNodeName); 
    if (!root_node){ err(ERR_FILE_INVALID,path); return 0; } 
    return 1; 
} 

,我使用功能(读 “Hersteller.xml”/初始化类)代码:

bool loadHersteller(){ // v4 
    // Declare 
    char * bfr; 
    xml_document<> doc; 
    xml_node<> * rt_node; 

    // Get root node 
    if (!readXML(concatURL(PFAD_DATEN,"Hersteller.xml"), bfr, &doc, "Hersteller", rt_node)) return 0; 

    // Extract 
    if (!initHRST(rt_node)) return 0; // Works fine on it's own (initializes a class) 
    toConsoleHrst(); // Works fine on it's own (prints data back to console) 

    // Clean up 
    delete[] bfr; 
    doc.clear(); 
    return 1; 
} // END loadHersteller() 

现在我从得到的是一个空白控制台并与它坠毁,返回一个整数。 我非常确定问题是char数组的范围或生命周期。这个函数的目标是完成检索xml文件/为我分配缓冲区并向我传递根节点(我将传递给另一个函数)的所有工作。如前所述,char数组需要在调用函数的范围内保持活跃状态​​,因此可以通过解析器构建的指针结构访问它。

+1

尝试将'buffer'传递为'char *&'。 – dlf

+0

'root_node'一样的东西。 – dlf

+0

现在,它的工作原理!我将原型中的'*'改为'*&'。我需要做的就是解决这个问题吗?我非常感谢在这种情况下对这是如何成为问题的准确描述。谢谢dlf! – Sam

回答

1

为了解决这个问题,同时通过您的输出参数(bufferroot_node)作为char*&(参考字符指针),而不是只需char*。否则,readXML()收到的是两个指针的副本,并且当函数返回并且它们被销毁时,分配给这些副本的任何值都会丢失。

注意:代码中存在潜在的内存泄漏,因为如果readXml()initHRST()失败并且该函数返回提前,则delete[]指令将不会被触及。

-1

而不是char *,声明函数参数为char **。在函数内部,参数名称的前缀为*。例如,*buffer = new char[length + 1]

当传递变量的函数,具有&前缀它:

if (!readXML(...), &bfr, ...

+1

2 downvotes? '**'可能需要比'*&'多一点心理体操,但它仍然是正确的...... – dlf

相关问题