2014-06-10 115 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

相關問題