使用malloc和new - C ++

时间:2013-02-25 11:39:44

标签: c++ malloc

我是C / C ++的新手,也是开发C ++应用程序的人。我遇到new和malloc的问题。我的应用程序有点复杂,也有一些C结构。在某些时候,我想为MyData类型的Class(包含一个deque)分配新的内存,后来我将该指针分配给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()方法。我的问题是,将mall_back项目推送到此malloc指针的deque是否可以,因为我只为指针分配了内存? malloc可以为deque处理动态内存分配吗?

6 个答案:

答案 0 :(得分:6)

以简化的方式说明您的情况:

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

q = p;

free(q);
free(p);

你能发现问题吗?

答案 1 :(得分:2)

如果你主要使用push_back元素,那么使用deque是没有意义的。与向量插入相比,它在推回元素方面更慢,在push_front中更快。同样使用malloc只是问问题。对于new,使用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;
 }

答案 2 :(得分:0)

malloc和new之间的区别在于,第一个不会调用类的构造函数,而后者则不会。在这种情况下,构造函数依次调用成员变量的构造函数,就像deque_MyDataSet一样。所以你所做的不会调用双端队列的构造函数。

始终在C++中使用new来避免以后出现问题。并确保一切都正确初始化。

答案 3 :(得分:0)

混合malloc()new是一个坏主意。什么是“C类”?

无论如何,这个:

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

错了,你没有分配正确的内存量。你的意思是:

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

因为您必须指向MyData结构的实际大小。你的代码只为指针分配了足够的空间,这不是你的意思。

请注意,在C ++中需要强制转换,但是bad practice in C

答案 4 :(得分:0)

  

我的问题是push_back项是否可以在这个malloc指针上使用deque,因为它只为指针分配了内存?

通常,无论如何初始化(动态分配或在堆栈上),都可以将项目推送到对象中。但在这种情况下,p_Data已分配,但根本没有初始化。

要看到这一点,您需要了解malloc和new之间的区别:

malloc是一个C函数,它分配一块内存并返回一个(void)指针。它在C ++中存在的原因是因为C ++最初与C兼容并且能够使用它的库(现在它是向后兼容性所必需的。

new是C ++运算符,它分配一块内存,将其解释为一个对象,并透明地调用该对象的构造函数。这两个功能不可互换。

为对象分配内存时,请始终使用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语句分配的内存(因为它们都指向同一地址)。

这应该被视为访问冲突错误。

答案 5 :(得分: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;
}