C ++函数,它动态地将char数组缓冲区分配给传递的char *

时间:2014-06-10 19:17:32

标签: c++ pointers dynamic-memory-allocation

我正在创建一个使用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数组需要在调用函数的范围内保持活动状态,因此可以通过解析器构建的指针结构访问它。

2 个答案:

答案 0 :(得分:1)

要解决此问题,请将您的输出参数(bufferroot_node)作为char*&(对char指针的引用)传递,而不是简单地char*。否则,readXML()接收的是两个指针的副本,并且当函数返回并且它们被销毁时,您分配给这些副本的任何值都将丢失。

注意:代码中可能存在内存泄漏,因为如果delete[]readXml()失败并且函数提前返回,则无法访问initHRST()指令。< / p>

答案 1 :(得分:-1)

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

将变量传递给函数时,请在其前面添加&

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