C++ C++;--对于本例,如何编写正确的代码来释放分配的内存?
基于此,, 我认为发布的代码存在内存泄漏b/c数组中存储的分配内存从未释放。我做了如下修改:C++ C++;--对于本例,如何编写正确的代码来释放分配的内存?,c++,C++,基于此,, 我认为发布的代码存在内存泄漏b/c数组中存储的分配内存从未释放。我做了如下修改: #include "stdafx.h" #include <iostream> using namespace std; class Giant { public: Giant() { m_id = s_next++; } void fee() { cout << m_id << "-fee
#include "stdafx.h"
#include <iostream>
using namespace std;
class Giant
{
public:
Giant()
{
m_id = s_next++;
}
void fee()
{
cout << m_id << "-fee ";
}
void phi()
{
cout << m_id << "-phi ";
}
void pheaux()
{
cout << m_id << "-pheaux ";
}
private:
int m_id;
static int s_next;
};
int Giant::s_next = 0;
// Define a Command interface with a method signature like execute().
class Command
{
public:
typedef void(Giant:: *Action)();
Command(Giant *object, Action method)
{
m_object = object;
m_method = method;
}
void execute()
{
(m_object->*m_method)();
}
private:
Giant *m_object;
Action m_method;
};
template <typename T> class Queue
{
public:
Queue()
{
m_add = m_remove = 0;
}
void enque(T *c)
{
m_array[m_add] = c;
m_add = (m_add + 1) % SIZE;
}
T *deque()
{
int temp = m_remove;
m_remove = (m_remove + 1) % SIZE;
return m_array[temp];
}
private:
enum
{
SIZE = 8
};
T *m_array[SIZE];
int m_add, m_remove;
};
int main()
{
Queue<Command> que;
Command *input[] =
{
new Command(new Giant, &Giant::fee),
new Command(new Giant, &Giant::phi),
new Command(new Giant, &Giant::pheaux),
new Command(new Giant, &Giant::fee),
new Command(new Giant, &Giant::phi),
new Command(new Giant, &Giant::pheaux)
};
// 24 / 4 = 6
size_t arrSize = sizeof(input)/sizeof(input[0]);
for (int i = 0; i < 6; i++)
que.enque(input[i]);
for (int i = 0; i < 6; i++)
que.deque()->execute();
cout << '\n';
// I add the following code to release the memory, however I am not sure
// whether o not this is enough
// There are two memory allocations in this code
// 1-> new command and 2->new Giant
// I think my code only release the memory allocated by new command.
// Is this correct?
for (int i = 0; i < 6; i++)
{
delete input[i];
input[i] = NULL;
}
}
#包括“stdafx.h”
#包括
使用名称空间std;
阶级巨人
{
公众:
巨人()
{
m_id=s_next++;
}
无效费用()
{
cout您是正确的-删除输入[i]
只会删除命令的实例
,而不会删除巨人的实例您是正确的-删除输入[i]
将只删除命令的实例,而不是巨人的实例。您是正确的。存在泄漏。您是正确的。存在泄漏
我认为我的代码只释放新命令分配的内存。这是正确的吗
是的,这是正确的。但是
你为什么还要在堆上分配它们呢?只要在堆栈上创建它们,并在需要的地方传递指针,那么你就不会忘记释放它们
Giant giant;
std::vector<Command> input;
input.push_back(Command(&giant, &Giant::fee));
input.push_back(Command(&giant, &Giant::phi));
input.push_back(Command(&giant, &Giant::pheaux));
input.push_back(Command(&giant, &Giant::fee));
input.push_back(Command(&giant, &Giant::phi));
input.push_back(Command(&giant, &Giant::pheaux));
// ...
for (int i = 0; i < input.size(); i++)
que.enque(&input[i]);
巨人;
向量输入;
input.push_back(命令(&giant,&giant::fee));
input.push_back(命令(&giant,&giant::phi));
input.push_back(命令(&giant,&giant::pheaux));
input.push_back(命令(&giant,&giant::fee));
input.push_back(命令(&giant,&giant::phi));
input.push_back(命令(&giant,&giant::pheaux));
// ...
对于(int i=0;i
你应该查找RAII习惯用法。C++中的一个坏习惯是在构造函数之外的任何地方放置<代码>新<代码>(除非直接传递给智能指针)。,将
delete
放在析构函数之外的任何位置都是不好的做法。尝试一次分配多个对象,而不将每个对象分别包装在RAII或智能指针中也是不好的
您可以编写不使用RAII/smart指针的代码,但要保证在任何情况下都不会出现内存泄漏,尤其是在代码中任何地方抛出异常时,这将是非常困难的
另外,您可以使用现有的队列数据结构,而不是滚动自己的队列数据结构。我强烈建议您避免滚动自己的数据结构,除非您真的必须这样做,或者您特别尝试了解数据结构在内部如何工作(并且您没有将该代码投入生产).这段代码似乎是成员函数指针的演示,因此我认为队列实现的复杂性是偶然的
改用std::queue
我认为我的代码只释放新命令分配的内存。这是正确的吗
是的,这是正确的。但是
你为什么还要在堆上分配它们呢?只要在堆栈上创建它们,并在需要的地方传递指针,那么你就不会忘记释放它们
Giant giant;
std::vector<Command> input;
input.push_back(Command(&giant, &Giant::fee));
input.push_back(Command(&giant, &Giant::phi));
input.push_back(Command(&giant, &Giant::pheaux));
input.push_back(Command(&giant, &Giant::fee));
input.push_back(Command(&giant, &Giant::phi));
input.push_back(Command(&giant, &Giant::pheaux));
// ...
for (int i = 0; i < input.size(); i++)
que.enque(&input[i]);
巨人;
向量输入;
input.push_back(命令(&giant,&giant::fee));
input.push_back(命令(&giant,&giant::phi));
input.push_back(命令(&giant,&giant::pheaux));
input.push_back(命令(&giant,&giant::fee));
input.push_back(命令(&giant,&giant::phi));
input.push_back(命令(&giant,&giant::pheaux));
// ...
对于(int i=0;i
你应该查找RAII习惯用法。C++中的一个坏习惯是在构造函数之外的任何地方放置<代码>新<代码>(除非直接传递给智能指针)。,将
delete
放在析构函数之外的任何位置都是不好的做法。尝试一次分配多个对象,而不将每个对象分别包装在RAII或智能指针中也是不好的
您可以编写不使用RAII/smart指针的代码,但要保证在任何情况下都不会出现内存泄漏,尤其是在代码中任何地方抛出异常时,这将是非常困难的
另外,您可以使用现有的队列数据结构,而不是滚动自己的队列数据结构。我强烈建议您避免滚动自己的数据结构,除非您真的必须这样做,或者您特别尝试了解数据结构在内部如何工作(并且您没有将该代码投入生产).这段代码似乎是成员函数指针的演示,因此我认为队列实现的复杂性是偶然的
改为使用std::queue
。“我认为我的代码只释放新命令分配的内存。这是否正确?”
是的,如果你的意思是我认为你的意思的话。命令
实例被解除分配。但是每个命令
实例都有一个指向动态分配的巨人
的指针,这个巨人没有解除分配
解决这个特殊程序的一个简单方法是不使用动态分配
更一般地说,根据需要使用容器类,如std::queue
和智能指针,如std::auto_ptr
干杯&hth.,“我想我的代码只会释放新命令分配的内存。这是正确的吗?”
是的,如果你的意思是我认为你的意思的话。命令
实例被解除分配。但是每个命令
实例都有一个指向动态分配的巨人
的指针,这个巨人没有解除分配
解决这个特殊程序的一个简单方法是不使用动态分配
更一般地说,根据需要使用容器类,如std::queue
和智能指针,如std::auto_ptr
干杯,您需要使用智能指针来表示所有权:
就个人而言,我将使用队列对象作为所有者。
但还有其他选择(您的解决方案可能非常依赖于您尚未阐明的上下文)
例如,对象input
可以拥有所有权,但您需要将其从一个简单的数组转换为您自己的数组
void enque(std::auto_ptr<T> c) // This explicitly tells the caller that you are
// taking ownership and they should not try and manage
// object after you receive it.
Queue<Command> que;
Giant giant;
Command input[] =
{
Command(&giant, &Giant::fee),
Command(&giant, &Giant::phi),
Command(&giant, &Giant::pheaux),
Command(&giant, &Giant::fee),
Command(&giant, &Giant::phi),
Command(&giant, &Giant::pheaux)
};
// 24 / 4 = 6
size_t arrSize = sizeof(input)/sizeof(input[0]);
for (int i = 0; i < arrSize; i++)
que.enque(input+i);