|
It's telling you you created heap objects and never deleted them. For every new that's executed there needs to be a delete.
You may need to add destructors to some of your classes to delete anything the class allocates.
Think about the lifetime of everything you create with new. Are you overwriting the only pointer to an object (orphaning it)?
|
|
|
|
|
Have a look at "HOWTO: Use _crtBreakAlloc to Debug a Memory Allocation"
Article ID: Q151585 in the MSDN.
|
|
|
|
|
if you make a variable with new, use delete.
if you make an array of variables with new, use delete[].
--
Peace,
Amit Jain
|
|
|
|
|
Does VC++ distinguish between delete and delete[] then? With most compilers the [] is no more than a comment.
|
|
|
|
|
Hm, I wonder if that's a bug with VC++ or the other compilers? But yes, VC++ DEFINITELY distinguishes between the two... You should too, just in case.
--
Peace,
Amit Jain
|
|
|
|
|
In order to properly delete an array (call the destructors of each element) the delete routine must work out the size of the array from hidden runtime information, probably the allocation size is stored immediately before the pointer. It would follow that there's very little point in using a separate delete implementation for arrays and single object allocations (a single object allocation being indistinguishable from an array of length 1).
|
|
|
|
|
I'm sure that's true and all, but regardless, if you're doing it in VC++, you're using delete[] for a dynamically allocated array, and delete for a single item.
--
Peace,
Amit Jain
|
|
|
|
|
Yes you should (for clarity at least).
I'd be surprised, though, if it makes any difference to the code generated.
|
|
|
|
|
> I'd be surprised, though, if it makes any difference to
> the code generated.
It makes a substantial difference. If you use new to allocate an array of objects and delete without square brackets, the destructors will not be called except one for element at 0th index.
CMyClass *p = new CMyClass[10];
// ... use p
delete p; // error -> only one d'tor call
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
You're right. Surprised I am . It even comes up with an error message.
|
|
|
|
|
Hello,
I know very little about C++ and what I do know has been classes compiled on Borlands free command line compiler. I have a task to complete with VC++, and after opening it up got scared looking at all those buttons and menus. Nether the less, a job is a job.
I need to create a COM dll file that I can access via ASP or VB. I've searched the web for this stuff and can't find much at all.
I found the ATL COM app wizard and setup a basic DLL outline, then added a new ATL object. I added a method to that and at this stage can compile the lot and view the dll from VB.
My problem (at this stage) seems to be returning any value from the component. VB seems to recorgnise it as a Sub as opposed to a Function. Also, if I try to give the method any other return value appart from HRESULT I get into trouble.
So how do I make a call like "a = b.Add(4, 6)" in VB to get the result retruned into a?
I can see my next problem coming, how do I return an array??
Thanks anyone
Lea
|
|
|
|
|
In the IDL you must define:
[out, retval] BSTR* strVal
[out, retval] int* nVal
etc;
Carlos Antollini.
|
|
|
|
|
OK, like I said I don't have a clue. So you mean like this?
[id(1), helpstring("method Add")] HRESULT Add([out, retval] BSTR* strVal);
And then what about the function in the class, how do I assign my newly created and calculated value to it? like this?
strVal = myNewNumber;
and the class itself, do I add in the same as above? like this??
STDMETHODIMP Ccalc::Add([out, retval] BSTR* strVal) { ..
Thanks
Lea
|
|
|
|
|
>[id(1), helpstring("method Add")] HRESULT Add([out, retval] BSTR* strVal);
Ok. This is if you want to return a value, but if you need from VB something like this:
b = obj.Add(1,2)
Must be:
[id(1), helpstring("method Add")] HRESULT Add([in] int nVal1, [in]int nVal2, [out, retval] BSTR* strVal);
>And then what about the function in the class
STDMETHODIMP Ccalc::Add(int nVal1, int nVal2, BSTR* strVal)
{
CString strBuff = _T("Val to return");
//Do something
::SysFreeString(*strVal);
*strVal = strBuff.AllocSysString();
}
Do you Understand?
Good Luck
Carlos Antollini.
|
|
|
|
|
Nearly there. This is a stupid one, but the CString (which I haven't used before) doesn't seem to work.
OK OK, forget that, how do I return an array to VB? Or even a string?
char anArray[2];
cpystr(anArray[0], "hello");
cpystr(anArray[1], ello");
*strVal = anArray;
Anything like this??
Lea
|
|
|
|
|
Nearly there. This is a stupid one, but the CString (which I haven't used before) doesn't seem to work.
OK OK, forget that, how do I return an array to VB? Or even a string?
char anArray[2];
cpystr(anArray[0], "hello");
cpystr(anArray[1], "world");
*strVal = anArray;
Anything like this??
Lea
|
|
|
|
|
I need to log method calls and entries. Next to that I also have to log values of those methods arguments and return values.
I tried to do this by writing a macro that using a stl stringstream to dump the arguments but it crashes on arguments that are not defined yet, yep NULL pointes.
I tried to overload the operator<< as following:
template <typename type="">
std::wostringstream& operator << (std::wostringstream &stream, const type *value)
{
if(value != NULL)
{
stream << *value;
}
else
{
stream << L"NULL";
}
return stream;
};
...but this did not work. Does somebody know a way to make this work?
regards,
Brian
|
|
|
|
|
> it crashes on arguments that are not defined yet, yep NULL pointes
Try to be more specific: what kind of crash it is?
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
Well here is a small example project:
#include "stdafx.h"
#include <sstream>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
stringstream ss;
unsigned long *ul = NULL;
ul = new unsigned long(10);
ss << *ul << endl;
cout << ss.str();
return 0;
}
The code in this project works fine, but if you take away the line that assigns a new value to 'ul' then you will cause an access violation. I want to prevent this from happening, but don't know how to do this nicely in my tracer code.
|
|
|
|
|
What's the relationship of this sample and overloaded operator you've posted first? Even with overloaded operator << you'll get GPF - you are dereferencing NULL pointer (when ul isn't assigned to 'new long[10]').
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
I just needed a method that could log all different kinds of arguments without having to check if the arguments were NULL pointers. I now solved it like this:
#define INTERNAL_CALL_MSG(id,msg); CTracer tracer(id); tracer << msg; tracer.Enter();
class CTracer
{
public:
CTracer(std::wstring methodId) : m_methodId(methodId)
{};
virtual void Enter()
{
LogMethodEntry(m_methodId, m_message.str());
};
virtual ~CTracer()
{
LogMethodExit(m_methodId);
};
template<typename type=""> CTracer& operator << (type &arg)
{
if (arg)
{
m_message << arg << L" ";
}
else
{
m_message << L"0 ";
}
return *this;
};
private:
std::wostringstream m_message;
std::wstring m_methodId;
}
void CSomeClass::CSomeMethod(unsigned long *arg1, BSTR *arg2)
{
INTERNAL_CALL_MSG(L"CSomeClass::CSomeMethod", *arg1 << arg2);
...do some actual work...
}
This work fine, except there is now way of telling if an argument is an actual NULL pointer or a some pointer to 0 as there isn't realy a difference.
|
|
|
|
|
INTERNAL_CALL_MSG(L"CSomeClass::CSomeMethod", *arg1 << arg2);
I'm giving up - what are you trying to achieve using *arg1 << arg2?
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
I'm using Windows NT 4.0 and Visual C++...
Anyone knows how to verify if a process is running in other machine whitout use registry key handles ?
|
|
|
|
|
Hello folks!
I'm a beginner in MFC and I've got a small problem - at least I hope so
I'm trying to change the font in a listbox and to do that I used the following code:
void CSimaskra2View::OnInitialUpdate()
...
CFont font;
font.CreatePointFont(8, _T("Arial"), NULL);
m_listi.SetFont(&font);
...
The only thing that happens is that the font changes (no problems there) but the result is some default, ugly font (NOT Arial)! It doesn't matter if I change to Times New Roman, or if I change the size, I always get the same font!
If I erase the m_listi.SetFont(&font); I get the "wonderful" default font of Windows again
Please help me .. I need it
thatman
|
|
|
|
|
Your font is destroyed at the end of OnInitialUpdate. Make it a member of view class.
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|