I've written a server and client program using CSockets. (I didn't come
across the "Don't ever do that" postings about CSockets until I was deep into
the implementation).
My programs work quite well. But they continually consume more and more
memory until the whole thing crashes. If I stop it at some point (while
debugging with the VS IDE) and return to the IDE, it never reports any memory
leaks. Yet, when I run the program and watch the memory usage of the
application via the Windows Task Manager I can see its memory usage going up
and up and up endlessly.
I did some tests that are basically:

int n;
for (n = 0 ; n < 10000 ; +=n)
{
CSocket* pSocket = CSocket*) new CSocket;
pSocket->Create(0);
delete pSocket;
}

That is, it merely allocates a CSocket and then deletes it.
Wnen I go through this loop I can watch the memory usage go up and up.
Clearly, the delete of the CSocket is not entirely deleting everything.
And I get the same kind of issues with CSocketFile and CArchive. They all
fail to fully delete.
My application absolutely MUST be able to create CSockets and CSoekctFiles
and CArchive as needed, since it's a Server.

Is there a solution to the problem of not fuilly deleting CSockets, etc.?

Re: CSocket : Consuming Memory Uncontrollably by Nishant

Nishant
Mon Aug 22 23:21:36 CDT 2005

Try calling Close before delete-ing it.

--
Regards,
Nish [VC++ MVP]
http://www.voidnish.com
http://blog.voidnish.com


"Roger Garrett" <RogerGarrett@discussions.microsoft.com> wrote in message
news:B94DE0D2-B3E1-43AF-8E44-D02648AC1DCF@microsoft.com...
> I've written a server and client program using CSockets. (I didn't come
> across the "Don't ever do that" postings about CSockets until I was deep
> into
> the implementation).
> My programs work quite well. But they continually consume more and more
> memory until the whole thing crashes. If I stop it at some point (while
> debugging with the VS IDE) and return to the IDE, it never reports any
> memory
> leaks. Yet, when I run the program and watch the memory usage of the
> application via the Windows Task Manager I can see its memory usage going
> up
> and up and up endlessly.
> I did some tests that are basically:
>
> int n;
> for (n = 0 ; n < 10000 ; +=n)
> {
> CSocket* pSocket = CSocket*) new CSocket;
> pSocket->Create(0);
> delete pSocket;
> }
>
> That is, it merely allocates a CSocket and then deletes it.
> Wnen I go through this loop I can watch the memory usage go up and up.
> Clearly, the delete of the CSocket is not entirely deleting everything.
> And I get the same kind of issues with CSocketFile and CArchive. They all
> fail to fully delete.
> My application absolutely MUST be able to create CSockets and CSoekctFiles
> and CArchive as needed, since it's a Server.
>
> Is there a solution to the problem of not fuilly deleting CSockets, etc.?
>
>



Re: CSocket : Consuming Memory Uncontrollably by Ulrich

Ulrich
Tue Aug 23 05:37:53 CDT 2005

Roger Garrett wrote:
> CSocket* pSocket = CSocket*) new CSocket;
> pSocket->Create(0);
> delete pSocket;

Other than the missing Close() call (which I can barely believe), don't use
new/delete the way you would do it in Java and specifically not in such an
insecure way (consider exceptions!). Also, I guess the above typo was a
cast which is unnecessary, dangerous and only serves to hide errors - don't
do it unless you really know that you have to and then, use C++ style
casts.

Uli


Re: CSocket : Consuming Memory Uncontrollably by RogerGarrett

RogerGarrett
Tue Aug 23 09:51:04 CDT 2005

Nishant,

I do indeed close the CSocket before deleting. I've tried all sorts of
approaches and nothing works. It always leaves memory un-reclaimed.

- Roger



Re: CSocket : Consuming Memory Uncontrollably by RogerGarrett

RogerGarrett
Tue Aug 23 09:51:10 CDT 2005

Uli,

The snippet of code that I posted is a simplification of the actual code. I
do actually Close the socket. I also tried simply using a CSocket as in:

{
CSocket MySocket;
MySocket.Create(0);
etc.....
}

and that also results in consumed-but-not-released memory. I tried the
pointer approach as an attempt to explicitly get rid of the object, but that
doesn't work either.

As for casting to (CSocket*), it is indeed necessary to cast when using the
new operator, otherwise you get a compiler error "cannot convert from void*
to CSoekct*", since by default the new operator returns a void pointer.

Is there some other way to cast? I've been doing it that way for 15 years
with no problems.

- Roger


And CAsyncSocket shows the same symptoms ! by RogerGarrett

RogerGarrett
Tue Aug 23 11:28:10 CDT 2005

Yielding to the advice that I shouldn't be using CSocket at all but rather
should be using CAsyncSocket I did some testing of that as well. And it, too,
consumes huge quantities of memory, never releasing it.

How does anyone ever write a server program that doesn't end up consuming
all memory?

I'm really at a dead end here.

Please, somebody provide some advice !

Re: And CAsyncSocket shows the same symptoms ! by Nemanja

Nemanja
Tue Aug 23 13:03:36 CDT 2005

Are you sure your leaks are socket related at all? I suggest you use
some leak detector, like this one:

http://www.codeproject.com/tools/visualleakdetector.asp


Re: And CAsyncSocket shows the same symptoms ! by RogerGarrett

RogerGarrett
Tue Aug 23 14:53:06 CDT 2005

Nemanja Trifunovic ,

I am quite certain that it's the CSocket (and CAsyncSocket) that's leaking
memory. I can step through the loop in my code that only does the CSocket
creation and deletion and watch the memory usage go up and up (via the
Windows Task Manager). As the memory is increasing the only thing that's
happenning is CSocket creation and (supposedly) deletion.

I'll give that memory checker a try, although I have used other means of
detecting memory problems and they all point to the Sockets.

THank you,

Roger



Re: CSocket : Consuming Memory Uncontrollably by Nikolaos

Nikolaos
Tue Aug 23 15:20:43 CDT 2005

Roger Garrett wrote:
> Uli,
>
> The snippet of code that I posted is a simplification of the actual code. I
> do actually Close the socket. I also tried simply using a CSocket as in:
>
> {
> CSocket MySocket;
> MySocket.Create(0);
> etc.....
> }
>
> and that also results in consumed-but-not-released memory. I tried the
> pointer approach as an attempt to explicitly get rid of the object, but that
> doesn't work either.

Can you define what you mean by "consumed but not released"? How did
you determine that?

> As for casting to (CSocket*), it is indeed necessary to cast when using the
> new operator, otherwise you get a compiler error "cannot convert from void*
> to CSoekct*", since by default the new operator returns a void pointer.

The new operator must return void* (not only the default new, but even
class-specific derivations of it) and the rationale is clearly explained
in "The Design and Evolution of C++" and there should be no need to cast
because "new" is special and the compiler knows it. I do things like
"MyClass *pClass = new MyClass" all the time and have never had an error
come up. As a matter of fact, I just tested the following code: "CSocket
*pSock = new CSocket" and did not get any errors. Have you actually
gotten an error?

> Is there some other way to cast? I've been doing it that way for 15 years
> with no problems.

Some people favor the C++ style casts (dynamic_cast<>, static_cast<>,
const_cast<> and reinterpret_cast<>) over the C-style casts. There are
arguments to be made for the C++ style ones, but in the end it's what
you're more comfortable with. I mix and match casts depending on what it
is that I am doing.

-n

Re: CSocket : Consuming Memory Uncontrollably by Aslan

Aslan
Tue Aug 23 21:12:29 CDT 2005


"Roger Garrett" <RogerGarrett@discussions.microsoft.com>, haber iletisinde
þunlarý yazdý:B94DE0D2-B3E1-43AF-8E44-D02648AC1DCF@microsoft.com...
> I've written a server and client program using CSockets. (I didn't come
> across the "Don't ever do that" postings about CSockets until I was deep
into
> the implementation).
> My programs work quite well. But they continually consume more and more
> memory until the whole thing crashes. If I stop it at some point (while
> debugging with the VS IDE) and return to the IDE, it never reports any
memory
> leaks. Yet, when I run the program and watch the memory usage of the
> application via the Windows Task Manager I can see its memory usage going
up
> and up and up endlessly.
> I did some tests that are basically:
>
> int n;
> for (n = 0 ; n < 10000 ; +=n)
> {
> CSocket* pSocket = CSocket*) new CSocket;
> pSocket->Create(0);
> delete pSocket;
> }
>
> That is, it merely allocates a CSocket and then deletes it.
> Wnen I go through this loop I can watch the memory usage go up and up.
> Clearly, the delete of the CSocket is not entirely deleting everything.
> And I get the same kind of issues with CSocketFile and CArchive. They all
> fail to fully delete.
> My application absolutely MUST be able to create CSockets and CSoekctFiles
> and CArchive as needed, since it's a Server.
>
> Is there a solution to the problem of not fuilly deleting CSockets, etc.?
>
>
Make sure you call "delete pSocket;" thing in the same thread you called
CSocket* pSocket = new CSocket;
How would you do that, I don't know, but I think it is THE problem!




Re: CSocket : Consuming Memory Uncontrollably by Aslan

Aslan
Tue Aug 23 23:56:29 CDT 2005


"Aslan" <Aslanski2002@yahoo.com>, haber iletisinde þunlarý
yazdý:OrgXIFFqFHA.2076@TK2MSFTNGP14.phx.gbl...
>
> "Roger Garrett" <RogerGarrett@discussions.microsoft.com>, haber iletisinde
> þunlarý yazdý:B94DE0D2-B3E1-43AF-8E44-D02648AC1DCF@microsoft.com...
> > I've written a server and client program using CSockets. (I didn't come
> > across the "Don't ever do that" postings about CSockets until I was deep
> into
> > the implementation).
> > My programs work quite well. But they continually consume more and more
> > memory until the whole thing crashes. If I stop it at some point (while
> > debugging with the VS IDE) and return to the IDE, it never reports any
> memory
> > leaks. Yet, when I run the program and watch the memory usage of the
> > application via the Windows Task Manager I can see its memory usage
going
> up
> > and up and up endlessly.
> > I did some tests that are basically:
> >
> > int n;
> > for (n = 0 ; n < 10000 ; +=n)
> > {
> > CSocket* pSocket = CSocket*) new CSocket;
> > pSocket->Create(0);
> > delete pSocket;
> > }
> >
> > That is, it merely allocates a CSocket and then deletes it.
> > Wnen I go through this loop I can watch the memory usage go up and up.
> > Clearly, the delete of the CSocket is not entirely deleting everything.
> > And I get the same kind of issues with CSocketFile and CArchive. They
all
> > fail to fully delete.
> > My application absolutely MUST be able to create CSockets and
CSoekctFiles
> > and CArchive as needed, since it's a Server.
> >
> > Is there a solution to the problem of not fuilly deleting CSockets,
etc.?
> >
> >
> Make sure you call "delete pSocket;" thing in the same thread you called
> CSocket* pSocket = new CSocket;
> How would you do that, I don't know, but I think it is THE problem!
>
Addition. Your example code is run in one thread. But I don't think your
actual code runs in the same thread, right?

OK. I ran your example.
At the start:
Private bytes: 640K
Working set: 2652K
Handles: 48
GDI handles: 10
User handles: 15

At the exit:
Private bytes: 676K
Working set: 2772K
Handles: 52
GDI handles: 10
User handles: 15

Yes there is a small increase but with such a pace it would run for a very
long time, how long it takes until your whole thing crashes? This might be a
problem related to number of handles becoming 52 from 48 because I didn't
see any leak being reported at the end of the run.

I used process explorer v9.12 by www.sysinternals.com for the above.

>
>



Re: CSocket : Consuming Memory Uncontrollably by Ulrich

Ulrich
Wed Aug 24 01:35:05 CDT 2005

Roger Garrett wrote:
> {
> CSocket MySocket;
> MySocket.Create(0);
> etc.....
> }
>
> and that also results in consumed-but-not-released memory.

In that case, I'd say it's a bug in class CSocket. Maybe it is also an issue
with you not reading the instructions close enough (although I personally
consider it a bug when one needs to do something special for such a case in
order not to leak memory). However, my experience with CSocket is rather
limited, so i can't comment on that.

> As for casting to (CSocket*), it is indeed necessary to cast when using
> the new operator, otherwise you get a compiler error "cannot convert from
> void* to CSoekct*", since by default the new operator returns a void
> pointer.

I'm not too far into the exact naming, but there is a
'new-operator' (basically an allocation function) and there is 'new'.
Invoking new like you did first invokes the new operator to allocate mem
and then creates an object on top of that mem (by invoking the ctor).

In any case, there is no casting at all invoked. Also, not when invoking
delete, because there the same principle applies, just in reverse. If you
first cast the pointer to void before passing it to delete, it is undefined
behaviour by the standard but in general the effect is that the dtor
(including that of all members!) is not called, leading to resource and
memory leaks.

BTW: I seriously wonder where you have the idea from that you need to cast
the result of new. If you have any books that claim this, they are probably
so far outdated that they are only interesting for a historian. Go to the
book reviews section at http://accu.org and pick a good one.

> Is there some other way to cast? I've been doing it that way for 15 years
> with no problems.

You never by accident casted away const or volatile? You never converted an
integer to a pointer? You never converted between to incompatible pointers?
So much changed in C++ during the last 15 years, and really lots of what
was common and good then isn't today. Someone else already suggested the
four C++ style casts, which only convert a singe aspect of the passed
object and are therefore safer. I'd like to add that Boost has some
functions that are intended to extend these casts like boost::numeric_cast
(with range checking), boost::lexical_cast (converts between e.g. strings
and numbers with intermediate streams) and a few more.

Uli


Re: CSocket : Consuming Memory Uncontrollably by msalters

msalters
Wed Aug 24 09:26:11 CDT 2005


Nikolaos D. Bougalis schreef:

> Roger Garrett wrote:
> > As for casting to (CSocket*), it is indeed necessary to cast when using the
> > new operator, otherwise you get a compiler error "cannot convert from void*
> > to CSoekct*", since by default the new operator returns a void pointer.
>
> The new operator must return void* (not only the default new, but even
> class-specific derivations of it) and the rationale is clearly explained
> in "The Design and Evolution of C++" and there should be no need to cast
> because "new" is special and the compiler knows it. I do things like
> "MyClass *pClass = new MyClass" all the time and have never had an error
> come up.

You're confusing operator new [the behind-the-scenes memory allocator]
and the new expression (which uses operator new, but also the ctor).
Operator new will return a void*, true, but you normally don't
use it. The form you showed (and the OP also used) is the new
expression.
It indeed returns a pointer to the desired type, because it guarantees
the ctor has run. So, the cast is not needed. If the OP got the error
message, it was because he used the wrong form of new. "Fixing" it with
a cast could cause memory corruption (which may look like a memory
leak)


Anyway, you should probably write
std::auto_ptr<MyClass> pClass ( new MyClass );
( except in ctors when initializing a single member, in which case
auto_ptr still is good advice )

HTH,
Michiel Salters


Re: CSocket : Consuming Memory Uncontrollably by Nikolaos

Nikolaos
Wed Aug 24 13:22:47 CDT 2005

msalters wrote:
> Nikolaos D. Bougalis schreef:
>
>
>>Roger Garrett wrote:
>>
>>>As for casting to (CSocket*), it is indeed necessary to cast when using the
>>>new operator, otherwise you get a compiler error "cannot convert from void*
>>>to CSoekct*", since by default the new operator returns a void pointer.
>>
>> The new operator must return void* (not only the default new, but even
>>class-specific derivations of it) and the rationale is clearly explained
>>in "The Design and Evolution of C++" and there should be no need to cast
>>because "new" is special and the compiler knows it. I do things like
>>"MyClass *pClass = new MyClass" all the time and have never had an error
>>come up.
>
>
> You're confusing operator new [the behind-the-scenes memory allocator]
> and the new expression (which uses operator new, but also the ctor).
> Operator new will return a void*, true, but you normally don't
> use it. The form you showed (and the OP also used) is the new
> expression.

Actually, I am not. I merely did not go in as much detail as you did,
in explaining the difference between "operator new" and a "new
expression" because it was not really necessary for the purposes of this
discussion.

Regardless, my description was accurate: I said "the new operator must
return void*" which is true, and that "new is special and the compiler
knows it" (translation: it forms a new-expression) so do you care to
tell me exactly what I am confused about, or what I said that was
inaccurate?

[And since you want to be anal about semantics, it's "new-expression"
not "new expression"]

> It indeed returns a pointer to the desired type, because it guarantees
> the ctor has run. So, the cast is not needed. If the OP got the error
> message, it was because he used the wrong form of new. "Fixing" it with
> a cast could cause memory corruption (which may look like a memory
> leak)

How is it possible for the following statement to not be construed as a
new-expression by a compiler:

CSocket *pSock = new CSocket;

-n