0

私は C/C++ が初めてで、C++ アプリケーションを開発しています。new と malloc に問題があります。私のアプリケーションは少し複雑で、C 構造体もいくつかあります。ある時点で、タイプ MyData (deque を含む) の Class に新しいメモリを割り当てたいと思い、後でそのポインターを C 構造体のポインターに割り当てました。私のコードの小さいバージョンは次のとおりです。

#include <deque>
class MyData 
{
public:
    MyData(){};
    ~MyData() {};

    std::deque<int>& GetDequeMyDataSet() {return deque_MyDataSet; };

private:
    std::deque<int>     deque_MyDataSet;//contains ohlc data for the symbol   
};

int _tmain(int argc, _TCHAR* argv[])
{
    MyData* pMyData = new MyData();
    MyData* p_Data = (MyData*)malloc(sizeof(MyData*));
    p_Data = pMyData;
    p_Data->GetDequeMyDataSet().push_back(10);
    p_Data->GetDequeMyDataSet().push_back(11);
    //.... Several other push back and operations releated to this deque goes here. 
    delete pMyData;// At the end I free both memories.
    free(p_Data);
    return 0;
}

両方のポインターにメモリを割り当てた後、malloc ポインター (p_Data) で GetDequeMyDataSet() メソッドを使用しました。私の問題は、ポインターのみにメモリを割り当てているため、この malloc ポインターの両端キューに項目を push_back してもよいかどうかです。malloc は deque の動的メモリ割り当てを処理できますか?

4

6 に答える 6

6

簡単に言えば、あなたの状況は次のとおりです。

void * p = malloc(1);
void * q = malloc(1);

q = p;

free(q);
free(p);

問題を見つけることができますか?

于 2013-02-25T11:42:36.460 に答える
2

主に要素を push_back する場合、deque を使用しても意味がありません。ベクトルの挿入と比較して、要素のプッシュバックは遅く、push_front は高速です。また、malloc を使用すると、問題が発生するだけです。クラス オブジェクトを動的に割り当てる必要がある場合は、std::shared_ptr または std::unique_ptr を使用します。彼らはあなたのためにメモリの解放を処理します。

 #include <vector>

 class MyData 
 {
 public:
     MyData() {};
     ~MyData() {};
     std::vector<int>& GetMyDataSet() { return m_myDataSet; }
 private:
     std::vector<int> m_myDataSet;
 };

 int _tmain(int argc, _TCHAR* argv[])
 {
     MyData myData;
     myData.GetMyDataSet().push_back(10);

     //or dynamically
     auto pMyData = std::make_shared<MyData>();
     pMyData->GetMyDataSet().push_back(10);


     return 0;
 }
于 2013-02-25T12:05:45.060 に答える
0

C ++では、多くの場合、動的に割り当てる必要はありません。必要なときに新しいオブジェクトを作成するだけです。

int _tmain(int argc, _TCHAR* argv[])
{
    MyData myData;   // No pointers, no new

    MyData* p_Data = &myData;   // Create a pointer to myData, if you need one
    p_Data->GetDequeMyDataSet().push_back(10);
    p_Data->GetDequeMyDataSet().push_back(11);
    //.... Several other push back and operations releated to this deque goes here. 

    // Nothing to delete or free here

    return 0;
}
于 2013-02-25T12:12:41.573 に答える
0

私の問題は、ポインターのみにメモリを割り当てているため、この malloc ポインターでアイテムをプッシュバックしてデキューしてもよいかどうかです。

通常、オブジェクトがどのように初期化されたか (動的に割り当てられたかスタックに割り当てられたか) に関係なく、アイテムをオブジェクトに push_back しても問題ありません。ただし、この場合p_Dataは割り当てられましたが、まったく初期化されていません。

これを確認するには、malloc と new の違いを理解する必要があります。

malloc は、メモリーのブロックを割り当て、そのメモリーへの (void) ポインターを返す C 関数です。C++ に存在する理由は、C++ が最初は C と互換性があり、そのライブラリを使用できるためです (現在では後方互換性のために必要です。

new は、メモリ ブロックを割り当て、それをオブジェクトとして解釈し、そのオブジェクトのコンストラクタを透過的に呼び出す C++ 演算子です。2 つの機能は互換性がありません。

オブジェクトにメモリを割り当てるときは、常に new を使用してください。malloc は、オブジェクトのコンストラクターを呼び出しません (また、オブジェクトのデストラクタを自由に呼び出しません)。

同等のコード:

class MyData { /* same as in your question */ };

// 1: normal C++ dynamic object allocation
MyData* pMyData = new MyData();

// 2: allocate through malloc and call constructor through placement new 
void*   block = (MyData*)malloc(sizeof(MyData)); // allocate sizeof(MyData) bytes
MyData* pMyData = new(block) MyData(); // call constructor on block memory

これは、malloc と free を使用すると、通常は (直感的に) オブジェクトが初期化されることを期待しているにもかかわらず、オブジェクトが初期化されないことを意味します。

TL:DR: C++ で malloc と free を使用しないでください。

両方のポインターをメモリに割り当てた後、malloc ポインター (p_Data) で GetDequeMyDataSet() メソッドを使用しました。

それはうまくいかなかったはずです。malloc されたポインタは初期化されるべきではありません (割り当てはあり、初期化はありません)。

その上、 を割り当てているためp_Data = pMyData;、 free への呼び出しは、delete ステートメントによって既に割り当てられているメモリを解放しようとします (両方が同じアドレスを指しているため)。

これは、アクセス違反エラーと見なされます。

于 2013-02-25T12:10:58.533 に答える
0

malloc と new の違いは、前者はクラスのコンストラクターを呼び出さず、後者は呼び出すことです。この場合と同様に、コンストラクターはメンバー変数のコンストラクターを呼び出しますdeque_MyDataSet。したがって、両端キューのコンストラクターは呼び出されません。

C++後で問題が発生しないように、常に new in を使用してください。そして、すべてが正しく初期化されるようにします。

于 2013-02-25T11:43:22.860 に答える
0

混合malloc()new悪い考えです。また、「Cクラス」とは何ですか?

とにかく、これ:

MyData* p_Data = (MyData*)malloc(sizeof(MyData*));

完全に間違っています。正しい量のメモリを割り当てていません。もしかして:

MyData* p_Data = (MyData *) malloc(sizeof *p_Data);

MyData指している構造の実際のサイズが必要なので。あなたのコードはthe pointerに十分なスペースしか割り当てていませんが、これはあなたが意味するものではありません。

キャストは C++ では必須ですが、 C では悪い習慣であることに注意してください。

于 2013-02-25T11:45:02.177 に答える