我正在创建一个使用RapidXML从xml文件中读取数据的C ++程序。因为RapidXML分配指向要用于访问它的xml内容的指针,所以只要在进一步的步骤中解析它,它就需要文件的内容。
所以我成功解析了几个文件,但是在每次解析文件的开始时,我总是把所有的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;
}
我使用该函数的代码(阅读&#34; Hersteller.xml&#34; /初始化类):
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数组需要在调用函数的范围内保持活动状态,因此可以通过解析器构建的指针结构访问它。
答案 0 :(得分:1)
要解决此问题,请将您的输出参数(buffer
和root_node
)作为char*&
(对char指针的引用)传递,而不是简单地char*
。否则,readXML()
接收的是两个指针的副本,并且当函数返回并且它们被销毁时,您分配给这些副本的任何值都将丢失。
注意:代码中可能存在内存泄漏,因为如果delete[]
或readXml()
失败并且函数提前返回,则无法访问initHRST()
指令。< / p>
答案 1 :(得分:-1)
而不是char *
,将函数参数声明为char **
。在函数内部,使用*
作为参数名称的前缀。例如,*buffer = new char[length + 1]
。
将变量传递给函数时,请在其前面添加&
:
if (!readXML(...), &bfr, ...