473,396 Members | 2,115 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

problem deleting char* used in threads

Hi all,

My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project. Both are
totally unmanaged. The gui app has a edit box, acting as a console, where I
send messages from dll to be displayed. The way I am sending messages is:
for sending the message:

void CGlobal::SendMessage(char * chptr )
{

extern HWND c_main_window_handle;
char * tmp = new char [ strlen ( chptr) +1 ];
strcpy ( tmp, chptr );
::SendMessage( c_main_window_handle, WM_DISPLAY_MSG, 200, (LPARAM)tmp);

}
(this function is somewhere inside the dll) any thread can call this class
and pass it any character array, it will create its own buffer, copy and
send its pointer to the gui thread.
The gui application has a file that has this function declared:

LRESULT proc_display_message(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam,
BOOL& /*bHandled*/)

proc_display_message receives the message and does something like this:
......
case 200:
char * ptr = (char * )lParam ;

diagtext->AppendText (ptr);
diagtext->AppendText ("\r\n");

delete [] ptr ; // this was allocated somewhere else and I plan to delete
it over here .
break;
.....
I get an error on the delete [] ptr line. It says:
-
Windows has triggered a breakpoint in OtengoGUI.exe.

This may be due to a corruption of the heap, and indicates a bug in
OtengoGUI.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information
-
and the debugger stops at the following line with a green pointer arrow:
-

void InsertText(int nInsertAfterChar, LPCTSTR lpstrText, BOOL bNoScroll =
FALSE, BOOL bCanUndo = FALSE)
{
SetSel(nInsertAfterChar, nInsertAfterChar, bNoScroll);
ReplaceSel(lpstrText, bCanUndo);
}<< ----------- this line

-
Why cant I delete a pointer that I got after casting from lParam parameter.
After all the allocation for this function was done on the heap and I should
be able to delete it anywhere else, thats what I was thinking.

Regards,

-ab.

Environment: visual studio 2k5, vc++ (unmanaged) WTL, windows 2000.
Aug 10 '06 #1
16 1553
Wim


"Abubakar" wrote:
Hi all,

My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project. Both are
totally unmanaged. The gui app has a edit box, acting as a console, where I
send messages from dll to be displayed. The way I am sending messages is:
for sending the message:

void CGlobal::SendMessage(char * chptr )
{

extern HWND c_main_window_handle;
char * tmp = new char [ strlen ( chptr) +1 ];
strcpy ( tmp, chptr );
::SendMessage( c_main_window_handle, WM_DISPLAY_MSG, 200, (LPARAM)tmp);

}
(this function is somewhere inside the dll) any thread can call this class
and pass it any character array, it will create its own buffer, copy and
send its pointer to the gui thread.
The gui application has a file that has this function declared:

LRESULT proc_display_message(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam,
BOOL& /*bHandled*/)

proc_display_message receives the message and does something like this:
......
case 200:
char * ptr = (char * )lParam ;

diagtext->AppendText (ptr);
diagtext->AppendText ("\r\n");

delete [] ptr ; // this was allocated somewhere else and I plan to delete
it over here .
break;
.....
I get an error on the delete [] ptr line. It says:
-
Windows has triggered a breakpoint in OtengoGUI.exe.

This may be due to a corruption of the heap, and indicates a bug in
OtengoGUI.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information
-
and the debugger stops at the following line with a green pointer arrow:
-

void InsertText(int nInsertAfterChar, LPCTSTR lpstrText, BOOL bNoScroll =
FALSE, BOOL bCanUndo = FALSE)
{
SetSel(nInsertAfterChar, nInsertAfterChar, bNoScroll);
ReplaceSel(lpstrText, bCanUndo);
}<< ----------- this line

-
Why cant I delete a pointer that I got after casting from lParam parameter.
After all the allocation for this function was done on the heap and I should
be able to delete it anywhere else, thats what I was thinking.

Regards,

-ab.

Environment: visual studio 2k5, vc++ (unmanaged) WTL, windows 2000.
Is your app and dll built with the same version of the crt ?

Wim
Aug 10 '06 #2

"Abubakar" <em**********@yahoo.coma écrit dans le message de news:
%2****************@TK2MSFTNGP05.phx.gbl...
Hi all,

My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project. Both
are
totally unmanaged. The gui app has a edit box, acting as a console, where
I
send messages from dll to be displayed. The way I am sending messages is:
for sending the message:
<snip>
-
Why cant I delete a pointer that I got after casting from lParam
parameter.
After all the allocation for this function was done on the heap and I
should
be able to delete it anywhere else, thats what I was thinking.
Both module (DLL and EXE) must be linked against the same DLL version of the
C-Runtime library : Compile both modules either with /MD, either with /MDd
(be sure it is the same for both modules!).
This is the sine qua non condition to pass dynamically allocated pointers
(as well as other CRT-state dependents variables, such as FILE*) across
modules boundaries.

Arnaud
MVP - VC


Aug 10 '06 #3
Why cant I delete a pointer that I got after casting from lParam
parameter.
After all the allocation for this function was done on the heap and I
should
be able to delete it anywhere else, thats what I was thinking.
In addition to the answers you already got, deleting memory that was
allocated in another module is often an indication of bad design because it
creates inter-module dependencies.
It will work if both the app and the dll link against the same version of
the dynamic crt, but it might save you a lot of troubles in the long run if
you change your design so that it is not necessary.

For example, I think you should be able to use SysAllocString to solve your
problems.
Those BSTRs are module independent, so they are not influenced by the crt.
--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Aug 10 '06 #4
Is your app and dll built with the same version of the crt ?

How do I know that they r using the same or different?

-Abubakar.

"Wim" <Wi*@discussions.microsoft.comwrote in message
news:46**********************************@microsof t.com...
>

"Abubakar" wrote:
Hi all,

My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project. Both
are
totally unmanaged. The gui app has a edit box, acting as a console,
where I
send messages from dll to be displayed. The way I am sending messages
is:
for sending the message:

void CGlobal::SendMessage(char * chptr )
{

extern HWND c_main_window_handle;
char * tmp = new char [ strlen ( chptr) +1 ];
strcpy ( tmp, chptr );
::SendMessage( c_main_window_handle, WM_DISPLAY_MSG, 200, (LPARAM)tmp);

}
(this function is somewhere inside the dll) any thread can call this
class
and pass it any character array, it will create its own buffer, copy and
send its pointer to the gui thread.
The gui application has a file that has this function declared:

LRESULT proc_display_message(UINT /*uMsg*/, WPARAM wParam, LPARAM
lParam,
BOOL& /*bHandled*/)

proc_display_message receives the message and does something like this:
......
case 200:
char * ptr = (char * )lParam ;

diagtext->AppendText (ptr);
diagtext->AppendText ("\r\n");

delete [] ptr ; // this was allocated somewhere else and I plan to
delete
it over here .
break;
.....
I get an error on the delete [] ptr line. It says:
-
Windows has triggered a breakpoint in OtengoGUI.exe.

This may be due to a corruption of the heap, and indicates a bug in
OtengoGUI.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information
-
and the debugger stops at the following line with a green pointer arrow:
-

void InsertText(int nInsertAfterChar, LPCTSTR lpstrText, BOOL bNoScroll
=
FALSE, BOOL bCanUndo = FALSE)
{
SetSel(nInsertAfterChar, nInsertAfterChar, bNoScroll);
ReplaceSel(lpstrText, bCanUndo);
}<< ----------- this line

-
Why cant I delete a pointer that I got after casting from lParam
parameter.
After all the allocation for this function was done on the heap and I
should
be able to delete it anywhere else, thats what I was thinking.

Regards,

-ab.

Environment: visual studio 2k5, vc++ (unmanaged) WTL, windows 2000.


Is your app and dll built with the same version of the crt ?

Wim

Aug 10 '06 #5
In this project I just agreed upon a pattern that all threads that want to
send messages to the gui console will use this method "cglobal::sendmessage"
by allocating char * with *new* and upon receiving the pointers the gui
thread will be responsible to delete them. Now the display part happens just
fine but the deleting gives problem as I stated earlier. I would try the
sysallocstring that u mentioned.

Thanks,

-ab.

"Bruno van Dooren [MVP VC++]" <br**********************@hotmail.comwrote
in message news:#1**************@TK2MSFTNGP06.phx.gbl...
Why cant I delete a pointer that I got after casting from lParam
parameter.
After all the allocation for this function was done on the heap and I
should
be able to delete it anywhere else, thats what I was thinking.

In addition to the answers you already got, deleting memory that was
allocated in another module is often an indication of bad design because
it
creates inter-module dependencies.
It will work if both the app and the dll link against the same version of
the dynamic crt, but it might save you a lot of troubles in the long run
if
you change your design so that it is not necessary.

For example, I think you should be able to use SysAllocString to solve
your
problems.
Those BSTRs are module independent, so they are not influenced by the crt.
--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"


Aug 10 '06 #6
Abubakar wrote:
In this project I just agreed upon a pattern that all threads that want to
send messages to the gui console will use this method "cglobal::sendmessage"
by allocating char * with *new* and upon receiving the pointers the gui
thread will be responsible to delete them. Now the display part happens just
fine but the deleting gives problem as I stated earlier. I would try the
sysallocstring that u mentioned.
SendMessage is synchronous (it doesn't return until the message has been
processed, in contrast to PostMessage, which returns immediately), so
you can safely delete the pointer in the calling method straight after
the call to SendMessage. That way the calling method can allocate the
memory any way it likes, or pass a string literal, etc. Passing around
ownership of raw pointers is a bad idea in general, but if you need to
do it, you need to precisely specify the allocation/deallocation
semantics (e.g. document that sysallocstring must be used).

Tom
Aug 10 '06 #7
My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project. Both
are
totally unmanaged. The gui app has a edit box, acting as a console, where
I
send messages from dll to be displayed. The way I am sending messages is:
for sending the message:

void CGlobal::SendMessage(char * chptr )
{

extern HWND c_main_window_handle;
char * tmp = new char [ strlen ( chptr) +1 ];
strcpy ( tmp, chptr );
::SendMessage( c_main_window_handle, WM_DISPLAY_MSG, 200, (LPARAM)tmp);

}
As ::SendMessage returns after it's already dispatched, so you can freely
delete the memory after that call.

--
Vladimir Nesterovsky
Aug 10 '06 #8
It would be wonderful if it can be done that way. But what I'm thinking is
that the UI thread would be executing its code asynchronously right ? What
if the pointer is used by the ui thread after the deletion has been done?

I'll try that.

Ab.

"Tom Widmer [VC++ MVP]" <to********@hotmail.comwrote in message
news:ep**************@TK2MSFTNGP03.phx.gbl...
Abubakar wrote:
In this project I just agreed upon a pattern that all threads that want
to
send messages to the gui console will use this method
"cglobal::sendmessage"
by allocating char * with *new* and upon receiving the pointers the gui
thread will be responsible to delete them. Now the display part happens
just
fine but the deleting gives problem as I stated earlier. I would try the
sysallocstring that u mentioned.

SendMessage is synchronous (it doesn't return until the message has been
processed, in contrast to PostMessage, which returns immediately), so
you can safely delete the pointer in the calling method straight after
the call to SendMessage. That way the calling method can allocate the
memory any way it likes, or pass a string literal, etc. Passing around
ownership of raw pointers is a bad idea in general, but if you need to
do it, you need to precisely specify the allocation/deallocation
semantics (e.g. document that sysallocstring must be used).

Tom

Aug 10 '06 #9
As ::SendMessage returns after it's already dispatched, so you can freely
delete the memory after that call.
do u mean that the sender thread (which is using the sendmessage) will going
to wait for the receiving thread to process the message and resume after the
receiving thread's message has been processed ?

-ab.

"Vladimir Nesterovsky" <vl******@nesterovsky-bros.comwrote in message
news:up**************@TK2MSFTNGP06.phx.gbl...
My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project. Both
are
totally unmanaged. The gui app has a edit box, acting as a console,
where
I
send messages from dll to be displayed. The way I am sending messages
is:
for sending the message:

void CGlobal::SendMessage(char * chptr )
{

extern HWND c_main_window_handle;
char * tmp = new char [ strlen ( chptr) +1 ];
strcpy ( tmp, chptr );
::SendMessage( c_main_window_handle, WM_DISPLAY_MSG, 200, (LPARAM)tmp);

}

As ::SendMessage returns after it's already dispatched, so you can freely
delete the memory after that call.

--
Vladimir Nesterovsky


Aug 10 '06 #10
It would be wonderful if it can be done that way. But what I'm thinking is
that the UI thread would be executing its code asynchronously right ?
SendMessage waits until the message has been handled before it returns.
This means that you can allocate before SendMessage, and deallocate after
SendMessage.
As long as the pointer is only used in the message handler that receives the
message, you will have no
problems at all.
What
if the pointer is used by the ui thread after the deletion has been done?
BOOM. Your program will crash.

Now if you implement it like I explained above, you should at least document
the reasoning behind your implementation.
It might be safe now, but if your design changes (for example, you start
using PostMessage), you will get all sorts of problems.

The solution with SysAllocString has the advantage that it will always work,
regardless of the way you send and process messages.

--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Aug 10 '06 #11
oh , got it, its been answered.

Thanks.
-ab.

"Abubakar" <em**********@yahoo.comwrote in message
news:u7**************@TK2MSFTNGP06.phx.gbl...
As ::SendMessage returns after it's already dispatched, so you can
freely
delete the memory after that call.

do u mean that the sender thread (which is using the sendmessage) will
going
to wait for the receiving thread to process the message and resume after
the
receiving thread's message has been processed ?

-ab.

"Vladimir Nesterovsky" <vl******@nesterovsky-bros.comwrote in message
news:up**************@TK2MSFTNGP06.phx.gbl...
My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project.
Both
are
totally unmanaged. The gui app has a edit box, acting as a console,
where
I
send messages from dll to be displayed. The way I am sending messages
is:
for sending the message:
>
void CGlobal::SendMessage(char * chptr )
{
>
extern HWND c_main_window_handle;
char * tmp = new char [ strlen ( chptr) +1 ];
strcpy ( tmp, chptr );
::SendMessage( c_main_window_handle, WM_DISPLAY_MSG, 200,
(LPARAM)tmp);
>
}
As ::SendMessage returns after it's already dispatched, so you can
freely
delete the memory after that call.

--
Vladimir Nesterovsky


Aug 10 '06 #12
Cool. I'll make a note that no one should change the sendmessage to
postmessage and to read these posts!

Thanks to all who replied.

-ab.

"Bruno van Dooren [MVP VC++]" <br**********************@hotmail.comwrote
in message news:#t**************@TK2MSFTNGP04.phx.gbl...
It would be wonderful if it can be done that way. But what I'm thinking
is
that the UI thread would be executing its code asynchronously right ?

SendMessage waits until the message has been handled before it returns.
This means that you can allocate before SendMessage, and deallocate after
SendMessage.
As long as the pointer is only used in the message handler that receives
the
message, you will have no
problems at all.
What
if the pointer is used by the ui thread after the deletion has been
done?
>
BOOM. Your program will crash.

Now if you implement it like I explained above, you should at least
document
the reasoning behind your implementation.
It might be safe now, but if your design changes (for example, you start
using PostMessage), you will get all sorts of problems.

The solution with SysAllocString has the advantage that it will always
work,
regardless of the way you send and process messages.

--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"


Aug 10 '06 #13
Hi Abubakar,
My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project. Both
are
totally unmanaged. The gui app has a edit box, acting as a console, where
I
send messages from dll to be displayed. The way I am sending messages is:
for sending the message:

void CGlobal::SendMessage(char * chptr )
{
extern HWND c_main_window_handle;
char * tmp = new char [ strlen ( chptr) +1 ];
strcpy ( tmp, chptr );
::SendMessage( c_main_window_handle, WM_DISPLAY_MSG, 200, (LPARAM)tmp);
}
(this function is somewhere inside the dll) any thread can call this class
and pass it any character array, it will create its own buffer, copy and
send its pointer to the gui thread.
The gui application has a file that has this function declared:

LRESULT proc_display_message(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam,
BOOL& /*bHandled*/)

proc_display_message receives the message and does something like this:
.....
case 200:
char * ptr = (char * )lParam ;

diagtext->AppendText (ptr);
diagtext->AppendText ("\r\n");

delete [] ptr ; // this was allocated somewhere else and I plan to
delete
it over here .
break;
....
I get an error on the delete [] ptr line.

Why cant I delete a pointer that I got after casting from lParam
parameter.
After all the allocation for this function was done on the heap and I
should
be able to delete it anywhere else, thats what I was thinking.
To answer that question: you have two distinct heaps. One from the crt
of your dll and one from the crt of your exe. So your exe's heap doesn't
contain the given pointer and cannot delete it. If you link both modules to
use the same crt instance they share the same heap.
But as a clean separation of modules cannot always ensure this
implementation detail (you might ship a new dll version which was
compiled with a new compiler thus using a new crt) you should not
rely on this.

In addition to Brunos suggestion to use SysAllocString you might also
consider to give your CGlobal class a member for freeing memory.
Assuming that CGlobal is exported from that dll and not only shared
in code, so that the implementation lives only in your dll you are
save to delete any memory in that function that was allocated in
another function of that dll:

void CGlobal::DeleteMessageString(char* p)
{
delete [] p;
}

Now you can savely call CGlobal::DeleteMessageString(ptr) in your exe
as the call is executing in your dll so that it is using the dlls crt heap.

Regards,
SvenC
Aug 11 '06 #14
Hi SvenC,

Thanks for the nice explanation. My process having 2 separate heaps really
sounds interesting :) and make things bit more clear to me. Can you give me
a link of some article that could explain this in detail ?

Regards,

-ab.

"SvenC" <Cv*************@moc.tfgwrote in message
news:OG**************@TK2MSFTNGP06.phx.gbl...
Hi Abubakar,
My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project. Both
are
totally unmanaged. The gui app has a edit box, acting as a console,
where
I
send messages from dll to be displayed. The way I am sending messages
is:
for sending the message:

void CGlobal::SendMessage(char * chptr )
{
extern HWND c_main_window_handle;
char * tmp = new char [ strlen ( chptr) +1 ];
strcpy ( tmp, chptr );
::SendMessage( c_main_window_handle, WM_DISPLAY_MSG, 200,
(LPARAM)tmp);
}
(this function is somewhere inside the dll) any thread can call this
class
and pass it any character array, it will create its own buffer, copy and
send its pointer to the gui thread.
The gui application has a file that has this function declared:

LRESULT proc_display_message(UINT /*uMsg*/, WPARAM wParam, LPARAM
lParam,
BOOL& /*bHandled*/)

proc_display_message receives the message and does something like this:
.....
case 200:
char * ptr = (char * )lParam ;

diagtext->AppendText (ptr);
diagtext->AppendText ("\r\n");

delete [] ptr ; // this was allocated somewhere else and I plan to
delete
it over here .
break;
....
I get an error on the delete [] ptr line.

Why cant I delete a pointer that I got after casting from lParam
parameter.
After all the allocation for this function was done on the heap and I
should
be able to delete it anywhere else, thats what I was thinking.

To answer that question: you have two distinct heaps. One from the crt
of your dll and one from the crt of your exe. So your exe's heap doesn't
contain the given pointer and cannot delete it. If you link both modules
to
use the same crt instance they share the same heap.
But as a clean separation of modules cannot always ensure this
implementation detail (you might ship a new dll version which was
compiled with a new compiler thus using a new crt) you should not
rely on this.

In addition to Brunos suggestion to use SysAllocString you might also
consider to give your CGlobal class a member for freeing memory.
Assuming that CGlobal is exported from that dll and not only shared
in code, so that the implementation lives only in your dll you are
save to delete any memory in that function that was allocated in
another function of that dll:

void CGlobal::DeleteMessageString(char* p)
{
delete [] p;
}

Now you can savely call CGlobal::DeleteMessageString(ptr) in your exe
as the call is executing in your dll so that it is using the dlls crt
heap.
>
Regards,
SvenC


Aug 13 '06 #15
Hi Abubakar,

"Abubakar" <em**********@yahoo.comwrote in message
news:%2****************@TK2MSFTNGP05.phx.gbl...
Hi SvenC,

Thanks for the nice explanation. My process having 2 separate heaps really
sounds interesting :) and make things bit more clear to me. Can you give
me
a link of some article that could explain this in detail ?
I did a quick search but didn't found too specific articles. You might want
to take a look at this:
http://msdn.microsoft.com/library/de...html/heap3.asp
Here you can see multiple heaps with the CRT heap as a private heap. If you
statically link to a CRT it will have a private heap of its own and another
module with a statically linked CRT will have another private heap. The
dynamically linked CRT has also a private heap but all of your modules which
use the dynamic CRT will use that private heap throughout process life time.

Here is a short discussion:
http://groups.google.de/group/micros...772c989b002616

At least that gives you some key words for googling around.

Regards,
SvenC
Regards,

-ab.

"SvenC" <Cv*************@moc.tfgwrote in message
news:OG**************@TK2MSFTNGP06.phx.gbl...
>Hi Abubakar,
My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project. Both
are
totally unmanaged. The gui app has a edit box, acting as a console,
where
I
send messages from dll to be displayed. The way I am sending messages
is:
for sending the message:

void CGlobal::SendMessage(char * chptr )
{
extern HWND c_main_window_handle;
char * tmp = new char [ strlen ( chptr) +1 ];
strcpy ( tmp, chptr );
::SendMessage( c_main_window_handle, WM_DISPLAY_MSG, 200,
(LPARAM)tmp);
}
(this function is somewhere inside the dll) any thread can call this
class
and pass it any character array, it will create its own buffer, copy
and
send its pointer to the gui thread.
The gui application has a file that has this function declared:

LRESULT proc_display_message(UINT /*uMsg*/, WPARAM wParam, LPARAM
lParam,
BOOL& /*bHandled*/)

proc_display_message receives the message and does something like this:
.....
case 200:
char * ptr = (char * )lParam ;

diagtext->AppendText (ptr);
diagtext->AppendText ("\r\n");

delete [] ptr ; // this was allocated somewhere else and I plan to
delete
it over here .
break;
....
I get an error on the delete [] ptr line.

Why cant I delete a pointer that I got after casting from lParam
parameter.
After all the allocation for this function was done on the heap and I
should
be able to delete it anywhere else, thats what I was thinking.

To answer that question: you have two distinct heaps. One from the crt
of your dll and one from the crt of your exe. So your exe's heap doesn't
contain the given pointer and cannot delete it. If you link both modules
to
>use the same crt instance they share the same heap.
But as a clean separation of modules cannot always ensure this
implementation detail (you might ship a new dll version which was
compiled with a new compiler thus using a new crt) you should not
rely on this.

In addition to Brunos suggestion to use SysAllocString you might also
consider to give your CGlobal class a member for freeing memory.
Assuming that CGlobal is exported from that dll and not only shared
in code, so that the implementation lives only in your dll you are
save to delete any memory in that function that was allocated in
another function of that dll:

void CGlobal::DeleteMessageString(char* p)
{
delete [] p;
}

Now you can savely call CGlobal::DeleteMessageString(ptr) in your exe
as the call is executing in your dll so that it is using the dlls crt
heap.
>>
Regards,
SvenC



Aug 14 '06 #16
Thanks, cool.

=ab.

"SvenC" <Cv*************@moc.tfgwrote in message
news:#z**************@TK2MSFTNGP05.phx.gbl...
Hi Abubakar,

"Abubakar" <em**********@yahoo.comwrote in message
news:%2****************@TK2MSFTNGP05.phx.gbl...
Hi SvenC,

Thanks for the nice explanation. My process having 2 separate heaps
really
sounds interesting :) and make things bit more clear to me. Can you give
me
a link of some article that could explain this in detail ?

I did a quick search but didn't found too specific articles. You might
want
to take a look at this:
http://msdn.microsoft.com/library/de...us/dngenlib/ht
ml/heap3.asp
Here you can see multiple heaps with the CRT heap as a private heap. If
you
statically link to a CRT it will have a private heap of its own and
another
module with a statically linked CRT will have another private heap. The
dynamically linked CRT has also a private heap but all of your modules
which
use the dynamic CRT will use that private heap throughout process life
time.
>
Here is a short discussion:
http://groups.google.de/group/micros...browse_thread/
thread/6ee1e13513452239/f5772c989b002616%23f5772c989b002616
>
At least that gives you some key words for googling around.

Regards,
SvenC
Regards,

-ab.

"SvenC" <Cv*************@moc.tfgwrote in message
news:OG**************@TK2MSFTNGP06.phx.gbl...
Hi Abubakar,

My solution consists of 2 projects, 1 is a dll (contains sockets
functionality, multithreaded), and the other is a wtl gui project.
Both
are
totally unmanaged. The gui app has a edit box, acting as a console,
where
I
send messages from dll to be displayed. The way I am sending messages
is:
for sending the message:

void CGlobal::SendMessage(char * chptr )
{
extern HWND c_main_window_handle;
char * tmp = new char [ strlen ( chptr) +1 ];
strcpy ( tmp, chptr );
::SendMessage( c_main_window_handle, WM_DISPLAY_MSG, 200,
(LPARAM)tmp);
}
(this function is somewhere inside the dll) any thread can call this
class
and pass it any character array, it will create its own buffer, copy
and
send its pointer to the gui thread.
The gui application has a file that has this function declared:

LRESULT proc_display_message(UINT /*uMsg*/, WPARAM wParam, LPARAM
lParam,
BOOL& /*bHandled*/)

proc_display_message receives the message and does something like
this:
.....
case 200:
char * ptr = (char * )lParam ;

diagtext->AppendText (ptr);
diagtext->AppendText ("\r\n");

delete [] ptr ; // this was allocated somewhere else and I plan to
delete
it over here .
break;
....
I get an error on the delete [] ptr line.

Why cant I delete a pointer that I got after casting from lParam
parameter.
After all the allocation for this function was done on the heap and I
should
be able to delete it anywhere else, thats what I was thinking.

To answer that question: you have two distinct heaps. One from the crt
of your dll and one from the crt of your exe. So your exe's heap
doesn't
contain the given pointer and cannot delete it. If you link both
modules
to
use the same crt instance they share the same heap.
But as a clean separation of modules cannot always ensure this
implementation detail (you might ship a new dll version which was
compiled with a new compiler thus using a new crt) you should not
rely on this.

In addition to Brunos suggestion to use SysAllocString you might also
consider to give your CGlobal class a member for freeing memory.
Assuming that CGlobal is exported from that dll and not only shared
in code, so that the implementation lives only in your dll you are
save to delete any memory in that function that was allocated in
another function of that dll:

void CGlobal::DeleteMessageString(char* p)
{
delete [] p;
}

Now you can savely call CGlobal::DeleteMessageString(ptr) in your exe
as the call is executing in your dll so that it is using the dlls crt
heap.
>
Regards,
SvenC



Aug 14 '06 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Manisha | last post by:
Hi, I am creating a C++ dll which is used to process data passed to it through one of its exported functions. It should be able to process 160 simultaneous requests. For this reason, I have...
5
by: Luke Dalessandro | last post by:
Code: Thread -> U -> T public class Thread { protected: thread_t _tid; virtual void foo() = 0; public: // Static entry function for the internal thread
14
by: Sweeya | last post by:
/*Program to do manipulations on a string*/ #include <iostream> using namespace std; class String { int len; char *p;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.