|
Hi,
I have a ActiveX component (3th party) in my own MFC project (Dialog, shared). If i run the project in developers studio i see some logging comming from the ActiveX component.
Now i want to write this logging to a file, without using developers studio. Somehow i don't get it to work. I tried to reroute the stdout/stderr stream, also the _CrtSetReportHook2 catches a lot...but not the activex logging.
Has anybody a idea how to get it done?
Many thanx,
Richard
|
|
|
|
|
Hi everyone!
My name's Duc , I'm from Vienam and I'm a student . I've just used
MFC(VC6.0).I think memory allocation is very important in programming,isn't it? I've tried to search in MSDN but it's not clear!So I want to ask you some question in my situation :
I have a class T which has a default destructor does nothing . T also
has a member variable : char *str; and a constructor :
T::T()
{
str=new char[200];
}
I allocate an object of class T in function f() by the new
operator like this :
void f()
{
T* pT=new T();
}
The question is : Will the memmory block(contains 200 bytes of str)
which is pointed to by pT be free(deallocated) when we leave the function
f()?What happens inside (when deallocating)?
Thank you for your listening and help!
Ky
|
|
|
|
|
HoDuc wrote:
I think memory allocation is very important in programming,isn't it
Yes, you can quickly go into real troubles
Ok, in your case, the memory allocated for your string won't be freed in your program. You need to free it in the destructor of your class:
T::~T()<br />
{<br />
if(str)<br />
{<br />
delete[] str;<br />
str = NULL;<br />
}<br />
}
[EDIT] Ok, I read your post a little bit to fast. One think that is really really important is that each new must have a corresponding delete to free the memory allocated by new. In your case, if you create a new object in your function, it won't be deleted automatically when leaving the function so you will first need to delete it. When deleting an object, this will automatically call the destructor of your class. And inside this destructor, you will free the memory allocated for your string. Easy, isn't it ? [\EDIT]
|
|
|
|
|
Ok, I will go a little bit deeper in details. It's true that it is a part that is not easy to understand at the begining.
The destructor of a class is there to free the memory that has been dynamically allocated (so with a new) for one or several member variables of your class (could do other things also but here we will just speak about the memory management). This is typically the place where you need to put the delete of str in your example. Even if the variable has not been allocated in the constructor for example !!
A good way of working is that if you don't allocate memory in the constructor for a pointer of your class, make it NULL:
T::T()<br />
{<br />
str = NULL;<br />
}
Thus, when you destructor will be called, you can check if this memory has been allocated or not and free it in the first case:
T::~T()<br />
{<br />
if(str)<br />
{<br />
delete[] str;<br />
str = NULL;<br />
}<br />
}
So, now when is the destructor of a class called ? Simple: whenever the object is being destroyed. By destroyed I mean not only when calling delete but also when your object (not allocated by new) goes out of scope. Example:
int foo()<br />
{<br />
T Object;<br />
....<br />
....<br />
return 0;<br />
}
In this case, your object has not been allocated dynamically but its destructor is called when the object is destroyed (leaving the function).
I hope this is a little bit clearer ? If you have further questions, do ask
|
|
|
|
|
HoDuc wrote:
Will the memmory block(contains 200 bytes of str)
which is pointed to by pT be free(deallocated) when we leave the function
no, it will free when a call of delete[] occurs, of when main leaves (and so, the system destroys the array)
HoDuc wrote:
What happens inside (when deallocating)?
if calls the destructors of each object in the tab before freeing the memory space... (soory, wrong)
it free the memory, even though the objects were "destructed"
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
T::T()
{str=new char[200];
}
void f()
{T* pT=new T();//no need to mention braces
}
in destructor u do the opposite of u did in CONSTRUCTOR
SO MENTION A DESTRUCTOR
T:~T()
{delete[] str;
}
in the void f()
delete pT; //mention in the f() where u dont require the
//pointer usually at the end of f()
which will call the above destructor
|
|
|
|
|
sunit5 wrote:
in destructor u do the opposite of u did in CONSTRUCTOR
No, not necessarily !! If you allocated your str elsewhere than in your constructor (and it happens very very often for me), you will have a memory leak then, because if I follow your rule, it won't be delete then...
Another thing: make 'safe destructions' before deleting an object, check if the pointer is not NULL, then delete the object and after that make it NULL (not really necessary but better be too much protective than the opposite ). And also, if your pointer is not allocated in the constructor, make it NULL so if it has not been yet allocated when your object is destroyed, it will not be deleted (and the opposite will result of a very very bad error message ).
So, a general rule I follow in my destructor: use this safe destruction for all pointers in your object and this is ok.
|
|
|
|
|
There is no point in part one of your safe destruction idea. The C++ delete operator takes care of the case where the pointer is NULL. So delete(NULL) is legal and does nothing. I do agree with your other ideas though, they are very helpful. Especially the bit about setting pointers to NULL on initialization..
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
I had serious doubts about your statement, "The C++ delete operator takes care of the case where the pointer is NULL." So I did some digging in the CRT library source. It turns out that this statement is not totally correct. The C++ delete operator just ends up calling _free_dbg and that checks for a null pointer. In the end the null pointer is caught though and that is the bottom line.
|
|
|
|
|
Rick York wrote:
I had serious doubts about your statement, "The C++ delete operator takes care of the case where the pointer is NULL." So I did some digging in the CRT library source. It turns out that this statement is not totally correct. The C++ delete operator just ends up calling _free_dbg and that checks for a null pointer. In the end the null pointer is caught though and that is the bottom line.
The C++ standard dictates that the delete operator must handle a NULL pointer being passed to it correctly. It makes no difference where, it will always be the case for a reasonably standards-compliant compiler/library (I don't know of any which don't obey this)
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
I checked VC++ 7.1's CRT implementation, it does check for NULL and return immediately (dbgdel.cpp, line 42). What compiler are you using?
I think it is just an inefficient implementation of the standard. The C++ standard pretty clearly says that the delete operator must handle the NULL pointer case.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
Hi all
In my dialog, i've many objects that are a RichEditCtrl, an some buttons.
I create with ClassWizard to add OnNotify in my app.
BOOL CCEdataTextEditorDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) <br />
{<br />
if( wParam == IDC_RICH )
{<br />
MessageBox("Non");
}<br />
MessageBox("hic");
<br />
return CDialog::OnNotify(wParam, lParam, pResult);<br />
}
But i get nothing!!
plz, help me! thanks for all
hzocm
|
|
|
|
|
Just to confirm... you are definitly getting no notifications? For example - try typing something, then select some of the text you typed. The selecting sould generate a notification event.
Joel Holdsworth
Wanna give me a job this summer?
Check out my online CV and project history[^]
|
|
|
|
|
no, there are nothing!
u know, in the end, that means after if (wParam == IDC_RICH){...} , we've MessageBox("blabla")
but it doesn't launch!
plz, help me!!
hzocm
|
|
|
|
|
Another possibility is that the notification messages are only routed to the specific event handlers. If you look in the class wizard, you should see events that are associated with this control only. Try adding handlers for these, and see if you get any luck.
Joel Holdsworth
Wanna give me a job this summer?
Check out my online CV and project history[^]
|
|
|
|
|
Have you used SetEventMask() to tell the rich edit control to send notifications? If you don't it won't send any.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
great!!!!!
thanks for your help and Joel Holdsworth too!
hzocm
|
|
|
|
|
Hi All,
I wonder who can tell me how to pass a string in DLL? For example, if I make 2 func as:
int IntTest()
{
int loc_int;
loc_int = 123;
return loc_int;
}
char *StrTest()
{
strcpy(glob_buf, "Hello from DLL");
return glob_buf;
}
In these 2 funcs, IntTest() works; but StrTest() does not despite it trys to pass a global buffer defined in header file. I used the DLL in my VB application, StrTest() did not work out(no hello-string appeared), but no error popped out.
Anybody can help me out? Any kind of hint is appreciated!
Huey
|
|
|
|
|
Hi All,
I wonder who can tell me how to pass a string in DLL? For example, if I make 2 func as:
int IntTest()
{
int loc_int;
loc_int = 123;
return loc_int;
}
char *StrTest()
{
strcpy(glob_buf, "Hello fro DLL");
return glob_buf;
}
In these 2 funcs, IntTest() works; but StrTest() does not despite it trys to pass a global buffer defined in header file. I used the DLL in my VB application, StrTest() did not work out(no hello-string appeared), but no error popped out.
Anybody can help me out? Any kind of hint is appreciated!
Huey
|
|
|
|
|
you must say somewhere in you dll that glob_buf is defined (see extern keyword).
otherwise, why not making this :
char* StrTest() {
char* Buff = new char[14];
::strcpy(Buff, "Hell from DLL");
return Buff;
}
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
Are you sure this will work ??
You try to write something at a NULL adress
Ok, but in fact the problem is not there. The problem is that VB and C++ don't use the same standard from strings. C++ uses zero-terminated strings and VB uses a kind of BSTR string (the length of the string is stored at the begning, each char takes 2 bytes and it is not zero-terminated).
You need to use a BSTR string inside your function and return it. I know this is a tricky problem and I spent a lot of time on this to find out a solution.
Sorry but I don't remeber exactly of the implementation details but take a look at BSTR strings (specifically this[^] article (and the functions at the end)
Hope this helps
|
|
|
|
|
This solution won't work neither
You will allocate memory in your dll and then return this string in the program. Two solutions: you don't delete the string -> this will result in a memory leak OR you delete the string and this will result in a runtime error because one basic rule is that the memory allocated by one process must be freed by the same process !! So here you allocate the string in the dll and free it in your program
|
|
|
|
|
If I understand your problem, you should allocate a string in the main process and pass his pointer to the dll function. In the dll function you can copy the string and then return to main process.
<br />
{<br />
char* str;<br />
str = new char[50];<br />
dll_func(str,50);<br />
<br />
<br />
}<br />
<br />
<br />
void dll_func(char* str, int max_size)<br />
{<br />
strcpy(str,"hallo world!");<br />
return;<br />
}<br />
|
|
|
|
|
Your idea was right as was your comment but your implementation does not use the max_size parameter. Shouldn't that be : strncpy( str, "hallo world", max_size ); ?
Just to be safe I would write the first part something like this :
<br />
<br />
const int strsize = 50;<br />
char* str;<br />
str = new char[strsize+1];<br />
dll_func(str,strsize);<br />
This way you will reserve a spot for a null character on the end.
|
|
|
|
|
Rick York wrote:
Your idea was right as was your comment but your implementation does not use the max_size parameter.
'couse I'm lazy! I thought that I solved that problem with my " //use max_size to prevent buffer overflow"
Rick York wrote:
Shouldn't that be : strncpy( str, "hallo world", max_size ); ?
yes.. this should a good implementation. Personally I usually use something like:
<br />
int dll_func(char* str,int max_size)<br />
{<br />
<br />
const char dll_str[] = "hallo world!";
<br />
strncpy(str,"hallo world!",max_size);<br />
return strlen(dll_str);<br />
}<br />
so in main process you can check (if (dll_func(str,strsize) > strsize) ) if you have truncated the string and the real/needed size.
Bye,
Francesco
|
|
|
|