Ok, this is turning out to be a long story. If you're not a programmer/geek, or don't enjoy a good story about 3 hours of toiling over C++ code came down to one two-word line of code... then move on. If not, here's the story:

This weekend, I decided to take up learning the QT Toolkit again. After programming for school and work, I'm usually burned out by the weekend. But, I'd had Spring Break a week before, so I wasn't.

Anyway. I was learning how to use QT's QSocket and QServerSocket classes, which are wrapper classes for TCP/IP communication. (ie: they encapsulate the functionality of a socket.) The "Hello World" equivalent for networking is usually an echo server. A connection is accepted, and everything sent to the server is echoed back.

Well, it's simple enough. I created a class which inherited from QServerSocket (MyServer), and a class inherited from QSocket (MySocket). MyServer would accept connections, and create a child MySocket, which would do all the work of echoing data. This way, many simultaneous connections could be handled.

Everything worked. Only, I realized I had a memory leak. Though my sockets were being closed at the appropriate time, I wasn't deleting them. So, just for practice, I set out to resolve this problem.

At first, I thought it would be rather simple. When the connection is closed, I'll just have the child tell its parent to delete it. (On a side note, the removeChild() method doesn't actually delete the child, so this wouldn't have solved my memory leak anyway.)

void sConnectionClosed() {  
   parent()->removeChild(this);
}

This compiled just fine, but segfaulted when a connection was closed. Well, hrmm. "Obviously, an object can't delete itself," I thought.

So then I set about creating a rather elaborate work-around. I made the MyServer class keep a list of all its MySocket children. Whenever a connection was accepted or closed, I polled all of those children... if they were idle (disconnected) I deleted them.

In theory, I would at have 0 or 1 dead connections lying about. When I actually tested the program, however... It turned out that my first dropped connection was deleted immediately, while it should have waited for another connection/disconnect to be deleted. I deduced that somehow, its state was being set to "Idle" before it announced its disconnection to the rest of the program. So, it told its parent to delete it, and it did.

Taken to its extreme, this all boils down to { delete this; } Which makes the mind boggle, but it works. (QT classes do reference counting, so this is "safe".)

I still haven't decided if { delete this; } is beautiful code, or kludge. Though, I'm leaning toward "both".

Log in or register to write something here or to contact authors.