|
Fist iam a newbie with MFC!
But i was asked to make an program that reads from the Comport, that is connected whit a windmachine.The windmachine sends me diffrent sort of kordinates(16 diffrent cords).
My problem here is that the user wants to choose how many kords he wants to display,my idea was to create a new ChildFrame for each kord that is selected to show.And store the ChildFrames in a array and if there comes new kords from the Comport use the ChildeFrame array to send right kords to the right ChildFrame.
The ChildFrame has a ChildView(CWnd derived) wich recives the kords for painting(OnPaint()).
I used the appwizzard (MDI,No doc/view)
I wounder if i am on the right track?
If u have a better soulotion for doing this a better way post a message here !
(Sorry my bad english)
|
|
|
|
|
when ever i run a program in debug mode, after i exit the program, i always get a message "Detected Memory Leak".. what do i do about it??? can you tell me where i am missing or making an error??
Nitish
|
|
|
|
|
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.
![Blush | :O](https://codeproject.freetls.fastly.net/script/Forums/Images/smiley_redface.gif)
|
|
|
|
|
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 ?
|
|
|
|