1

私は xerces-c を学びたいと思っており、オンラインでこのチュートリアルに従っていました。

http://www.yolinux.com/TUTORIALS/XML-Xerces-C.html

チュートリアルをコンパイルしてメモリ チェッカー (valgrind) で問題なく実行することができましたが、プログラムを少し変更すると、メモリ チェッカーが潜在的なリーク バイトを返しました。プログラムが 1 つではなく 2 つのファイルを読み取れるようにするために、main に数行追加しただけです。

int main()
{
   string configFile="sample.xml"; // stat file. Get ambigious segfault otherwise.

   GetConfig appConfig;

   appConfig.readConfigFile(configFile);

   cout << "Application option A="  << appConfig.getOptionA()  << endl;
   cout << "Application option B="  << appConfig.getOptionB()  << endl;

   // Added code
   configFile = "sample1.xml";
   appConfig.readConfigFile(configFile);

   cout << "Application option A="  << appConfig.getOptionA()  << endl;
   cout << "Application option B="  << appConfig.getOptionB()  << endl;

   return 0;
}

別の xml ファイルを読み取るために余分なコード行を追加したときに、次のような出力が得られるのはなぜだろうと思っていました。

==776== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==776== Command: ./a.out
==776== 
Application option A=10
Application option B=24
Application option A=30
Application option B=40
==776== 
==776== HEAP SUMMARY:
==776==     in use at exit: 6 bytes in 2 blocks
==776==   total heap usage: 4,031 allocs, 4,029 frees, 1,092,045 bytes allocated
==776== 
==776== 3 bytes in 1 blocks are definitely lost in loss record 1 of 2
==776==    at 0x4C28B8C: operator new(unsigned long) (vg_replace_malloc.c:261)
==776==    by 0x5225E9B: xercesc_3_1::MemoryManagerImpl::allocate(unsigned long) (MemoryManagerImpl.cpp:40)
==776==    by 0x53006C8: xercesc_3_1::IconvGNULCPTranscoder::transcode(unsigned short const*, xercesc_3_1::MemoryManager*) (IconvGNUTransService.cpp:751)
==776==    by 0x4038E7: GetConfig::readConfigFile(std::string&) (in /home/bonniehan/workspace/test/a.out)
==776==    by 0x403B13: main (in /home/bonniehan/workspace/test/a.out)
==776== 
==776== 3 bytes in 1 blocks are definitely lost in loss record 2 of 2
==776==    at 0x4C28B8C: operator new(unsigned long) (vg_replace_malloc.c:261)
==776==    by 0x5225E9B: xercesc_3_1::MemoryManagerImpl::allocate(unsigned long) (MemoryManagerImpl.cpp:40)
==776==    by 0x53006C8: xercesc_3_1::IconvGNULCPTranscoder::transcode(unsigned short const*, xercesc_3_1::MemoryManager*) (IconvGNUTransService.cpp:751)
==776==    by 0x40393F: GetConfig::readConfigFile(std::string&) (in /home/bonniehan/workspace/test/a.out)
==776==    by 0x403B13: main (in /home/bonniehan/workspace/test/a.out)
==776== 
==776== LEAK SUMMARY:
==776==    definitely lost: 6 bytes in 2 blocks
==776==    indirectly lost: 0 bytes in 0 blocks
==776==      possibly lost: 0 bytes in 0 blocks
==776==    still reachable: 0 bytes in 0 blocks
==776==         suppressed: 0 bytes in 0 blocks
==776== 
==776== For counts of detected and suppressed errors, rerun with: -v
==776== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
4

1 に答える 1

1

サンプル コードには、ユース ケースにいくつかの欠点があるようです。次のコードが含まれています。

m_OptionA = XMLString::transcode(xmlch_OptionA);

ドキュメントから、トランスコードでは、呼び出し元が返された (C スタイルの) 文字列の割り当てを解除する必要があることがわかりますXMLString::release()GetConfigこれがデストラクタで行われていることがわかります。

if(m_OptionA)   XMLString::release( &m_OptionA );

しかし、このコードは には存在しませんreadConfig()。そこに追加する必要があります。コンストラクターでこれらの C スタイルの文字列メンバーを NULL に初期化することもできます。そうしないとreadConfig()、1 回または 2 回ではなく 0 回呼び出すと、別のメモリの問題 (潜在的にクラッシュ バグ) に直面することになります。

于 2011-01-17T19:47:46.987 に答える