内存泄漏,删除[]不起作用? [英] Memory leak, delete [] not working?

查看:157
本文介绍了内存泄漏,删除[]不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,
我是C ++新手,所以如果这是一个简单的问题,我深表歉意.

我有一个子类,可以创建另一个类的动态对象数组.

头文件使用以下内容定义指针变量:

Hello all,
I am a bit of a C++ newbie, so I apologize if this is a simple question.

I have a child class that creates a dynamic array of objects of another class.

The header file uses the following to define the pointer variable:

Passenger * passengerList;



该类的构造方法正在为数组分配内存,如下所示:



The Constructor for the class is allocating the memory for the array as follows:

passengerList = new Passenger[10];



最后,析构函数具有以下代码来取消分配数组:



And finally the destructor has the following code to de-allocate the array:

delete [] passengerList;
passengerList = NULL;



这种内存分配产生了内存泄漏,我不知道为什么.我已经遍历了代码,跟踪了数组的分配,并看着它通过了析构函数并据称得到了重新分配.但是我仍然有内存泄漏.有什么理由无法删除.哦,执行期间没有任何错误.

谢谢


克里斯蒂安,我仔细检查了我的passenger 类,并且其中没有使用任何指针.另外,我正在使用以下内容进行泄漏检测.
其中包括:



This allocation of memory is producing a memory leak and I can''t figure out why. I have stepped through the code, tracked the allocation of the array and watched it pass through the destructor and supposedly get de-allocated. And yet I still have the memory leak. Is there any reason why a delete wouldn''t work. Oh, and no there aren''t any errors during execution.

Thanks


Christian, I double checked my passenger class and there aren''t any pointers used in it. Also, I''m using the following for my leak detection.
This is included:

#ifdef _WIN32
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif



随后在Main()中调用此函数:



Followed with this function call in Main():

#ifdef _WIN32
	_CrtDumpMemoryLeaks();
#endif



我读到这是一种适当的方法,但是正如我指出的那样,我是新手,并且愿意接受更好的方法.

ASPDOTNETDEV,这是实际使用数组的函数:



I read that this is a proper method, but as I pointed out I am a newbie and am open to better methods.

ASPDOTNETDEV, here is the function that actually uses the array:

const void MagicSchoolBus::addPassenger(const Passenger& p)
{
	int pc = this->GetPassengerCount();
	int mp = this->GetMaxPassengers();
	
	if (!this->GetRunningState())
	{
		if (pc < mp)
		{
			passengerList[pc] = p;
			this->SetPassengerCount(++pc);
			cout << "passenger added" << endl;
		}
		else
		{
			mp = mp + 10;
			Passenger * tempList = new Passenger[mp];
			for (int i = 0; i < pc; i++)
			{
				tempList[i] = passengerList[i];
			}
			delete [] passengerList;
			passengerList = tempList;
			this->SetMaxPassengers(mp);
			passengerList[pc] = p;
			this->SetPassengerCount(++pc);
			cout << "passenger added" << endl;
		}
	}
	else
	{
		cout << "Cannot add passengers while the vehicle is running" << endl;
	}			
}




正如您可能已经猜到的那样,这是我正在学习的编程课程.该项目已经上交,因为到期日期已经过去了,但是我拒绝让这个程序击败我,因此我决心找出是什么原因导致了泄漏.
再次感谢您的建议!

感谢大家的持续帮助.根据Aescleal的泄漏跟踪建议,我得到的泄漏报告与以前显示的相同,因此显然我确实确实存在泄漏.

根据要求,我在此处添加了Passenger构造函数和析构函数:




As one might have already guessed, this is for a programming course I am taking. The project has already been turned in because the due date has come and gone but I refuse to let this program beat me and I am determined to find out what is causing the leak.
Thanks again for the suggestions!

Thanks for the continued help everyone. Based on Aescleal''s leak tracking suggestion I am getting the same leaks reported that I showed before so apparently I really do have the leaks.

As requested I have added the Passenger constructors and destructor here:

Passenger::Passenger(void)
{
    passengerWeight = 0;
    strcpy_s(passengerName, "Default Name");
}
Passenger::Passenger(char pName[], int pWeight)
{
    passengerWeight = pWeight;
    strcpy_s(passengerName, pName);
}
Passenger::~Passenger(void)
{
}



另外,这是MagicSchoolBus类的完整构造函数和析构函数:



Also, here are the complete constructors and destructor for the MagicSchoolBus class:

MagicSchoolBus::MagicSchoolBus(void) : Car(0, 10, "Default MagicSchoolBus")
{
    Vehicle::SetMaxPassengers(10);
    passengerList = new Passenger[10];
    for (int i = 0; i < 10; i++)
    {
        passengerList[i] = Passenger();
    }
}
MagicSchoolBus::MagicSchoolBus(int fCap, int fRate, char name[MAXIMUM_NAME_SIZE]) : Car(fCap, fRate, name)
{
    Vehicle::SetMaxPassengers(10);
    passengerList = new Passenger[10];
    for (int i = 0; i < 10; i++)
    {
        passengerList[i] = Passenger();
    }
}
MagicSchoolBus::~MagicSchoolBus(void)
{
    delete [] passengerList;
    passengerList = NULL;
}




最后是在Main()中如何创建对象的方法:




Finally here is how the objects are created in Main():

MagicSchoolBus m1;
MagicSchoolBus m2(50, 5, "Craig''s Bus");



也是有趣的一点; m1是唯一存在内存泄漏的对象.即使构造器相同,m2对象也不会.

再次感谢大家.


好的,这是另一个数据点,对于以前没有提及此点,我深表歉意.我还会遇到在addPassenger函数期间复制passengerList数组时发生的内存泄漏.以前,m2对象不是内存泄漏的源头,因为我认为当addPassenger创建新的passengerList并且新的passengerList成为泄漏时,其内存被破坏了.

当我从Main移除m2.addPassenger调用时,我得出了这个结论.当我这样做时,除了m1的泄漏外,m2突然成为内存泄漏的根源.我还尝试向m1添加足够的乘客以强制创建新数组,它消除了原来的m1泄漏并将泄漏创建(或根据您的解释转移)到数组的新实例.

我怀疑存在某种范围问题,但不确定如何诊断.
谢谢


Aspdotnetdev,
这里要求提供SetPassengerCount和SetMaxPassengers函数.



Also an interesting point; m1 is the only object that has a memory leak. The m2 object does not, even though the contructors are identical.

Thanks again everyone.


Okay here is another data point and I apologize for not mentioning this before. I also get a memory leak that occurs when the passengerList array is copied during the addPassenger function. Previously, the m2 object wasn''t presenting as the source of a memory leak because I think its memory gets destroyed when addPassenger creates the new passengerList and the new passengerList becomes the leak.

I came to this conclusion when I removed the m2.addPassenger calls from Main. When I did this suddenly m2 became the source of a memory leak in addition to m1''s leak. I also tried adding enough passengers to m1 to force the creation of a new array and it removed the original m1 leak and created (or transfered depending on your interpretation) the leak to the new instance of the array.

I suspect some kind of scope issue but I''m not sure how to diagnose it.
Thanks


Aspdotnetdev,
As requested here are the SetPassengerCount and SetMaxPassengers functions.

const void Vehicle::SetPassengerCount(const int pc)
{
    passengerCount = pc;
}
const void Vehicle::SetMaxPassengers(const int mp)
{
    maxPassengers = mp;
}



如您所见,它们是非常简单的设置器,因此我看不到它们如何引起问题.但是我又是新手,而不是专家.还没有.

至于使用:
this->SetPassengerCount(++pc);

从行业角度来看,使用++ pc是否普遍被否定?这是我做的其中一件事,因为我知道它可以工作,而不必考虑任何被认为不好的编程实践.

根据您的建议,我尝试将tempList设置为NULL,但没有任何效果.
谢谢


我正在使用Visual Studio2008.已将项目压缩并放入Dropbox的公用文件夹中.可以从这里下载:
http://dl.dropbox.com/u/1262192/crgMustang_MemoryLeak_problem.zip [ ^ ]

我只想提前向碰巧看到此问题的任何人道歉.它不像我想要的代码那样干净,但是我迷恋于跟踪此内存泄漏,并一直进行到我的讲师截止日期为止,并最终以未完成的状态提交它.
但是,感谢那些花时间研究它的人.对我来说,正确处理这些东西很重要.



As you can see they are very simple setters so I don''t see how they could cause a problem. But then again I am the newb and not the expert; yet.

As for using:
this->SetPassengerCount(++pc);

Is using ++pc generally frowned upon from an industry perspective? Its one of those things I did because I know it works and wasn''t necessarily thinking about any perceived poor programming practice.

Per your suggestion I tried setting tempList to NULL but it had no effect.
Thanks


I''m using Visual Studio 2008. I have zipped up the project and put it in the public folder of my Dropbox. It can be downloaded from here:
http://dl.dropbox.com/u/1262192/crgMustang_MemoryLeak_problem.zip[^]

And I just want to apologize ahead of time to anyone who happens to look at this. Its not as clean as I like to have my code but I became obsessed with tracking down this memory leak and worked on it right up until my instructors deadline and wound up submitting it in this unfinished state.
But thanks to anyone who takes the time to look at it. It mean a lot to me to get this stuff right.

推荐答案

就像克里斯蒂安·克里斯蒂安所说,问题在于Passenger 类没有释放一些东西内存或您的分析器不正确.这对我来说很好:

Like Christian said, the problem is either that the Passenger class isn''t freeing up some memory or that your profiler is incorrect. This worked fine for me:

int * myInts;
for(int i = 0; i < 1000000; i++)
{
	myInts = new int[100];
	delete[] myInts;
}



您能否提供一个类似的示例来说明问题(包括您的Passenger 类)?



Can you provide a similar sample that demonstrates the issue (including your Passenger class)?


以下是一些建议:

*您的Passenger 类或struct 是否具有作为指针的成员?如果是这样,并且这些成员自己分配了空间,则必须在passengerList之前释放/删除这些指针.
* Passenger 的基类中是否有任何指针已单独分配了空间?它们也必须自己被释放/删除.

*这听起来似乎很明显,但是有没有执行delete [] 代码的执行路径?
Here are some suggestions:

* Does your Passenger class or struct have any members that are pointers? If so, and these members are allocated space on their own, these pointers will have to be freed/deleted before passengerList.

* Are there any pointers in the base class of Passenger that have been allocated space on their own? They would have to be freed/deleted on their own, as well.

* This might sound obvious, but are there any paths of execution in which the delete [] code is not being executed?


我快速浏览了一下您的代码,但没有编译器.如果您是我,我将注释掉您主要功能中的大部分代码.创建一辆魔术巴士并添加一名乘客,它会泄漏内存吗?如果再增加一位乘客呢?

您在堆栈上分配的其他对象之一可能是导致问题的原因.
您有大量的按引用复制,这使得代码难以遵循.如果您在Passenger的构造函数和析构函数中打印消息,则很可能会惊讶于您逐步遍历代码时调用它们的频率.现在,Passenger类现在不需要自定义副本构造函数或赋值运算符.

我认为问题与您在您的机票中重新声明旅客名单有关.车辆有一个,汽车,飞机,MagicBug,Xwing都有一个名为passengerList的成员(其他重复).有时它是一个大小不同的数组,有时是一个指针.在MagicBus成员函数中,通常使用"this-> passengerList"引用它,但在构造函数和析构函数中,使用"passengerList".我不确定编译器将如何解决这些问题,您几乎肯定需要在基类中具有单个数组(静态大小)或指针(动态大小),而没有其他数组.尝试提高警告级别,然后查看编译器的内容.

很少有其他事情

当传递要复制的字符串常量(如Pasenger的常量)时,应使用" const char * blah"而不是"char blah [somelength]",您需要传递的只是指针到字符串的开头.

当从基类调用成员函数时,通常不需要在基函数的名称前加上前缀.使用this->也是一样.这两件事都可能对虚拟功能造成意想不到的后果.我怀疑这是您遇到的问题.

我注意到在Fleets类中,添加车辆时不会增加vehicleCount.

来自内存跟踪器的报告也可能是错误的.它能给出泄漏物体的大小吗?有时这可能是一个线索.您可以使用linux吗? valgrind非常适合这种事情.

很抱歉,如果这个回复有点令人毛骨悚然,但来晚了,还喝了点酒
I had a quick look at your code but I dont have a compiler. If I were you I would comment out most of the code in your main function. Create one magic bus and add a single passenger, does it leak memory? How about if you add another passenger etc?

It may be that one of the other objects you''re allocating on the stack is the cause of your problem.

You have a lot of copy by reference going which makes the code harder to follow. If you print a message in the constructor and destructor of Passenger you''ll probaly be suprised how often they are called as you step through the code. The Passenger class as it is now doesnt require custom copy constructor or assignment operator though.

I think the problem relates to the fact you''re redeclared passengerList in your herichy. Vehicle has one, Car, Airplane, MagicBug, Xwing all have a member called passengerList (and others are repeated). Sometimes it''s an array of different sizes, sometimes its a pointer. In MagicBus member functions you usually reference it with ''this->passengerList'' but in the constructor and destructor you use ''passengerList''. I''m not sure how the compiler will resolve these, you almost certainly need to have a single array (static size) or pointer (dynamic size) in the base class and no other. Try turning up your warning level and see what the compiler says.

Few other things

When passing a string constant that you''re going to copy (like the contsructor of Pasenger) you should use ''const char* blah'' not ''char blah[somelength]'', all you need to pass is the pointer to the start of the string.

When calling a member function from a base class its not usually necessary to prefix it with the name of the base class. The same goes for using this->. Both of these things can cause unintended consequences with virtual functions. I suspect this is par tof your issue.

I noticed in the Fleets class you dont increment vehicleCount when adding a vehicle.

Its also possible that the reporting from the memory tracker is wrong. Does it give the size of the leaked object? This can be a clue sometimes. Do you have access to linux? valgrind is great for this kind of thing.

Sorry if this reply is a bit of amess but its late and had a few drinks


这篇关于内存泄漏,删除[]不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆