我是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处理动态内存分配吗?
答案 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;
}