2017-12-06 9 views
0

私はVisual Studio 2008をコンパイラとして使用しています。私はstd :: stringとして最初のパラメータを含み、struct CSVFileInfoとして2番目のパラメータを含むstdマップを持っています。私は、次のようにmemcpy関数を使用してCSVFileInfoの他の目的にイテレータ二番目のパラメータをコピーしようとしたリリースモードでのクラッシュではなく、デバッグモードで結果 2番目の格納値からデータをコピーする際の問題_Ty2秒のstd :: mapイテレータ

std::map<std::string, CSVFileInfo>::iterator iter; 
for(iter = csv_files.begin(); iter != csv_files.end(); iter++) 
{ 
    CSVFileInfo objCsv; 
    memcpy(&objCsv, &(iter->second), sizeof(CSVFileInfo)); 
} 

。次のように私はに私のコードを変更し、クラッシュ、

CSVFileInfo csvFileInfo; 
    csvFileInfo.m_csvHandler = iter->second.m_csvHandler; 
    csvFileInfo.m_file = iter->second.m_file; 
    csvFileInfo.m_fileNamePath = iter->second.m_fileNamePath; 
    csvFileInfo.m_is_running = iter->second.m_is_running; 
    csvFileInfo.m_item = iter->second.m_item; 
    csvFileInfo.m_outofService = iter->second.m_outofService; 
    csvFileInfo.m_readonly = iter->second.m_readonly; 
    csvFileInfo.m_start_option = iter->second.m_start_option; 
    csvFileInfo.m_thread = iter->second.m_thread; 

の代わりにmemcpy関数を見つけたとき私の構造体は、

struct CSVFileInfo 
    { 
     typedef boost::thread _csv_run_thread_; 
     bool m_outofService; 
     bool m_readonly; 
     bool m_is_running; 
     int m_start_option; 
     HTREEITEM m_item; 
     std::string m_fileNamePath; 
     std::string m_file; 
     CCSVHandler* m_csvHandler; 
     _csv_run_thread_ *m_thread; 

     CSVFileInfo() : m_outofService(false), m_readonly(false), m_thread(NULL), 
      m_is_running(false), m_csvHandler(NULL), m_item(NULL), m_start_option(100) 
     { 
     } 
    }; 

です。私は問題を修正した。

私の疑問はクラッシュに関するものですが、この状況でmemcpyがクラッシュしたのはなぜですか?

答えて

1

主な問題の1つは、std::memcpyを使用してオブジェクトをコピーすることです。

CSVFileInfo objCsv = iter->second; 

あなたが実際にコピーを必要としない場合は、代わりに参照を使用します:

CSVFileInfo &objCsv = iter->second; 
をあなたが本当に コピーが必要な場合、これは、単純なコピー・建設(あるいは割り当て)を行うことによって解決されなければなりませんそれは基本的にC++のコピーセマンティクス(コピー・建設、コピー代入)を無視し、バイト単位のコピーを行いますので、 std::memcpyを使用して

は面倒です。クラス内で他のクラスを使用している場合は、std::stringのメンバーが正しくコピーされないため、非常に問題になります。

C++コピーセマンティクスを使用すると、この問題が解決されます。

一般に、CスタイルのPOD objectを持っていない限り、オブジェクトを操作するためのCスタイルの関数は避けてください(例:memcpyまたはmemset以上)。

+0

私はstd :: memcpyではなく、Cベースのmemcpyを実際に使用しました。私は使用キーワードを一切使用していないことがわかります。このコードベースは古いコードベースであり、多くはこのコードで作業しました。 CとC++プログラマの両方がコードを処理しているので、両方のプログラマが混在しています。でも、私はクラスに構造体を変更することを考えたが、上記のコードが問題を解決し、それを維持したことがわかった。 –

+0

@SujithkVarghese C++をプログラミングしているなら、 'memcpy'と' std :: memcpy'は同じです。特に 'using namespace std;'がある場合。 –

+0

コードベースにnamespace stdを使用していません。それ以外はmemcpyとstd :: memcpyは同じですか?ご確認いただき、ありがとうございます。 –

関連する問題