Home > Archive > Unix Programming > July 2004 > C++ related problems with socket programming
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
C++ related problems with socket programming
|
|
| Andrew Falanga 2004-07-19, 4:00 pm |
| I asked this same question in alt.comp.lang.learn.c-c++ because the
problem is with a destructor and not with the non-standard C or C++ code
in the program. Or so I thought, I'm beginning to suspect otherwise
which is what brings me here. I'll essentially write the same skeleton
code here, at this point the program isn't large anyway because I'm
early on in the development of the library.
#include <iostream>
#include <sys/types.h>
#include <sys/sockets.h>
#include <netdb.h>
/* and a bunch of others */
class Sock {
private:
int s;
struct hostent *he;
struct sockaddr_in si;
public:
Sock() : s(-1)
{
he = new struct hostent;
memset(he, 0, sizeof(struct hostent));
memset(&si, 0, sizeof(struct sockaddr_in));
}
~Sock {
delete he;
}
// then there are member functions for displaying socket data
// writing data to the socket, etc.
}; // end of class definition
int main() {
Sock s1; //ctor is called here
// so some things like create a socket with member function
// fill hostent structure with a call to gethostbyname()
// display data
return 0; // here the destructor is called
}
Now, in the ctor, the new operator was used to reserve memory for the
hostent structure (*he). In the dtor, all I'm doing is deleting it.
Every time this program exits, I get a segmentation fault and I know
it's with the destructor. I've commented out the destructor from the
code and the program exits normally.
For kicks and grins, I wrote a very simple program that basically does
the same thing but without using library items. I define a simple
structure, create a class that contains a pointer to this struct and
then create a ctor and dtor for this class that essentially does the
same thing I'm doing in my socket program. However, my littler test
program exits normally with using a dtor to destroy the memory earlier
reserved with a call to new. So, what gives? What am I doing wrong?
---------------------------------------------
Andrew R. Falanga (a non-HP employee)
Hewlett-Packard Company
11311 Chinden Blvd.
Boise, Idaho
---------------------------------------------
Please note: The e-mail address is purposely
mangled. I do not wish my account at HP to
become a spam haven.
| |
| joe@invalid.address 2004-07-19, 4:00 pm |
| Andrew Falanga <falandrew@hp.com> writes:
> I asked this same question in alt.comp.lang.learn.c-c++ because the
> problem is with a destructor and not with the non-standard C or C++
> code in the program. Or so I thought, I'm beginning to suspect
> otherwise which is what brings me here. I'll essentially write the
> same skeleton code here, at this point the program isn't large anyway
> because I'm early on in the development of the library.
[...]
> Now, in the ctor, the new operator was used to reserve memory for
> the hostent structure (*he). In the dtor, all I'm doing is deleting
> it. Every time this program exits, I get a segmentation fault and I
> know it's with the destructor. I've commented out the destructor
> from the code and the program exits normally.
My guess would be that the pointer is getting stepped on by something
else in the program, or has been freed before the dtor runs by one of
the other member functions.
Try running it under a memory checker.
Joe
--
We can't all be heroes because someone has to sit on the curb and
clap as they go by.
- Will Rogers
| |
| Fletcher Glenn 2004-07-19, 4:00 pm |
|
Andrew Falanga wrote:
> I asked this same question in alt.comp.lang.learn.c-c++ because the
> problem is with a destructor and not with the non-standard C or C++ code
> in the program. Or so I thought, I'm beginning to suspect otherwise
> which is what brings me here. I'll essentially write the same skeleton
> code here, at this point the program isn't large anyway because I'm
> early on in the development of the library.
>
> #include <iostream>
> #include <sys/types.h>
> #include <sys/sockets.h>
> #include <netdb.h>
> /* and a bunch of others */
>
> class Sock {
> private:
> int s;
> struct hostent *he;
> struct sockaddr_in si;
>
> public:
> Sock() : s(-1)
> {
> he = new struct hostent;
> memset(he, 0, sizeof(struct hostent));
> memset(&si, 0, sizeof(struct sockaddr_in));
> }
> ~Sock {
> delete he;
> }
>
> // then there are member functions for displaying socket data
> // writing data to the socket, etc.
> }; // end of class definition
>
> int main() {
> Sock s1; //ctor is called here
>
> // so some things like create a socket with member function
> // fill hostent structure with a call to gethostbyname()
> // display data
>
> return 0; // here the destructor is called
> }
>
> Now, in the ctor, the new operator was used to reserve memory for the
> hostent structure (*he). In the dtor, all I'm doing is deleting it.
> Every time this program exits, I get a segmentation fault and I know
> it's with the destructor. I've commented out the destructor from the
> code and the program exits normally.
>
> For kicks and grins, I wrote a very simple program that basically does
> the same thing but without using library items. I define a simple
> structure, create a class that contains a pointer to this struct and
> then create a ctor and dtor for this class that essentially does the
> same thing I'm doing in my socket program. However, my littler test
> program exits normally with using a dtor to destroy the memory earlier
> reserved with a call to new. So, what gives? What am I doing wrong?
>
> ---------------------------------------------
> Andrew R. Falanga (a non-HP employee)
> Hewlett-Packard Company
> 11311 Chinden Blvd.
> Boise, Idaho
> ---------------------------------------------
> Please note: The e-mail address is purposely
> mangled. I do not wish my account at HP to
> become a spam haven.
The usual reason for a SEGV in a destructor is a corruption of the heap.
This kind of problem is notoriously hard to find as cause and effect are
often widely separated in time. The easiest way to troubleshoot this
is to use a heap checker program like Rational's Purify or Electric Fence.
--
Fletcher Glenn
| |
| Craig Barkhouse 2004-07-19, 4:00 pm |
|
"Andrew Falanga" <falandrew@hp.com> wrote in message
news:40fbe42f$1@usenet01.boi.hp.com...
> // fill hostent structure with a call to gethostbyname()
Well I can't see your code, but there could be a problem with this. If you
have a method in your class that does something like:
he = gethostbyname(name);
then you are changing what 'he' points to, and you can't expect to be able
to delete it.
| |
| Andrew Falanga 2004-07-19, 4:00 pm |
| Craig Barkhouse wrote:
> "Andrew Falanga" <falandrew@hp.com> wrote in message
> news:40fbe42f$1@usenet01.boi.hp.com...
>
>
>
> Well I can't see your code, but there could be a problem with this. If you
> have a method in your class that does something like:
> he = gethostbyname(name);
> then you are changing what 'he' points to, and you can't expect to be able
> to delete it.
>
>
You're absolutely right! I should have seen that, but of course
sometimes it's better to have a second set of eyes to look at things.
Thanks,
---------------------------------------------
Andrew R. Falanga (a non-HP employee)
Hewlett-Packard Company
11311 Chinden Blvd.
Boise, Idaho
---------------------------------------------
Please note: The e-mail address is purposely
mangled. I do not wish my account at HP to
become a spam haven.
| |
| Ulrich Eckhardt 2004-07-20, 3:59 pm |
| Andrew Falanga wrote:
> class Sock {
> private:
> int s;
> struct hostent *he;
> struct sockaddr_in si;
>
> public:
> Sock() : s(-1)
> {
> he = new struct hostent;
> memset(he, 0, sizeof(struct hostent));
> memset(&si, 0, sizeof(struct sockaddr_in));
> }
> ~Sock {
> delete he;
> }
>
> // then there are member functions for displaying socket data
> // writing data to the socket, etc.
> }; // end of class definition
Your code is breaking a basic rule of C++: either you implement all four of
default constructor, copy constructor, assignment operator and destructor
or you implement none of those.
Example:
Sock s1;
Sock s2 = s1; // oops, both instances' 'he' now have the same value.
Sock s3;
s3 = s2; // oops, s3's 'he' is lost and will never be deleted.
Take a look at the C++ FAQ at parashift.com, it's also in there.
Uli
--
http://www.erlenstar.demon.co.uk/unix/
| |
| Andrew Falanga 2004-07-28, 9:05 pm |
| > Your code is breaking a basic rule of C++: either you implement all four of
> default constructor, copy constructor, assignment operator and destructor
> or you implement none of those.
>
> Example:
> Sock s1;
> Sock s2 = s1; // oops, both instances' 'he' now have the same value.
> Sock s3;
> s3 = s2; // oops, s3's 'he' is lost and will never be deleted.
>
> Take a look at the C++ FAQ at parashift.com, it's also in there.
>
> Uli
>
I did go look in the FAQ at parashift.com. However, I was unable to
find a direct question related to this or answer. Is it spread across
multiple questions and answers? What question number is it?
---------------------------------------------
Andrew R. Falanga (a non-HP employee)
Hewlett-Packard Company
11311 Chinden Blvd.
Boise, Idaho
---------------------------------------------
Please note: The e-mail address is purposely
mangled. I do not wish my account at HP to
become a spam haven.
|
|
|
|
|