473,834 Members | 1,873 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

segfault with dynamic_cast

I get a segfault in the following scenario (I am not really used to
pointers...):

I have a base class Animal and a derived class Dog. Now I construct
two Dogs and store pointers to them in a set<Dog*>. Beforing storing,
the Dog pointers are passed through a function taking Animal pointers
and dynamic_cast'in g them to Dog pointers.

Looks good to me, but it segfaults. Why? Here is my code:
#include <iostream>
#include <stdexcept>
#include <set>
using namespace std;

class Animal {
public:
Animal(const string& theName):name(t heName){}
virtual ~Animal(){}
virtual void speak(){
cout << "I do not speak." << endl;
};
const string& name;
const string& getName(){retur n name;}
};

class Dog : public Animal {
public:
Dog(const string& n):Animal(n){}
virtual ~Dog(){}
virtual void speak(){
cout << "Woof. I am " << getName() << endl;
};
};

class Zoo {
public:
set<Dog*> dogs;
void addAnimal(Anima l* a){
Dog* d;
if((d = dynamic_cast<Do g*>(a))){
dogs.insert(d);
}else throw runtime_error(" Unknown animal");
}
};

int main(){
Zoo zoo;
Dog d1("Rex");
Dog d2("Rox");
zoo.addAnimal(& d1);
zoo.addAnimal(& d2);
for(set<Dog*>:: iterator it = zoo.dogs.begin( ); it !=
zoo.dogs.end(); ++it){
(*it)->speak();
}
}

// (I know that zoo::dogs should be private, I just made it public
here to make code shorter)

Thanks for your comments!
Markus
Jul 23 '05 #1
7 2068
Markus Dehmann wrote:
I get a segfault in the following scenario (I am not really used to
pointers...):

I have a base class Animal and a derived class Dog. Now I construct
two Dogs and store pointers to them in a set<Dog*>. Beforing storing,
the Dog pointers are passed through a function taking Animal pointers
and dynamic_cast'in g them to Dog pointers.

Looks good to me, but it segfaults. Why? Here is my code:


First make sure your compiler doesn't have some bogus mode to disable
RTTI.

Otherwise it looks ok to me. However, your code uses one of my peevish
constructs. I hate assignments as side effects of comparisons. This
is further aggravated by the fact that you don't initialize the variable
d. It would be better style to write it
Dog* d = dynmaic_cast<Do g*>(a);
if(d) ...

-Ron

Isn't Sirius the Dog*?
Jul 23 '05 #2
Markus Dehmann wrote:
I get a segfault in the following scenario (I am not really used to
pointers...):

I have a base class Animal and a derived class Dog. Now I construct
two Dogs and store pointers to them in a set<Dog*>. Beforing storing,
the Dog pointers are passed through a function taking Animal pointers
and dynamic_cast'in g them to Dog pointers.

Looks good to me, but it segfaults. Why? Here is my code:
#include <iostream>
#include <stdexcept>
#include <set>
using namespace std;

class Animal {
public:
Animal(const string& theName):name(t heName){}
virtual ~Animal(){}
virtual void speak(){
cout << "I do not speak." << endl;
};
const string& name;
const string& getName(){retur n name;}
};

class Dog : public Animal {
public:
Dog(const string& n):Animal(n){}
virtual ~Dog(){}
virtual void speak(){
cout << "Woof. I am " << getName() << endl;
};
};

class Zoo {
public:
set<Dog*> dogs;
void addAnimal(Anima l* a){
Dog* d;
if((d = dynamic_cast<Do g*>(a))){
dogs.insert(d);
}else throw runtime_error(" Unknown animal");
}
};

int main(){
Zoo zoo;
Dog d1("Rex");
Dog d2("Rox");
zoo.addAnimal(& d1);
zoo.addAnimal(& d2);
for(set<Dog*>:: iterator it = zoo.dogs.begin( ); it !=
zoo.dogs.end(); ++it){
(*it)->speak();
}
}

// (I know that zoo::dogs should be private, I just made it public
here to make code shorter)

Thanks for your comments!
Markus


you pass "Rex" and "Rox" to Dog::Dog(const string &) which
create a temporary string. g++ does not seem to find out
that this temporary is needed until d1 and d2 go out of scope.
I would say this is a bug in g++, as Sun's Studio compiler does
what you would expect it to do...

Tom
Jul 23 '05 #3

Markus Dehmann wrote:
I get a segfault in the following scenario (I am not really used to
pointers...):

I have a base class Animal and a derived class Dog. Now I construct
two Dogs and store pointers to them in a set<Dog*>. Beforing storing, the Dog pointers are passed through a function taking Animal pointers
and dynamic_cast'in g them to Dog pointers.

Looks good to me, but it segfaults. Why? Here is my code:
#include <iostream>
#include <stdexcept>
#include <set>
using namespace std;

class Animal {
public:
Animal(const string& theName):name(t heName){}
virtual ~Animal(){}
virtual void speak(){
cout << "I do not speak." << endl;
};
const string& name;

Change this to:

const string name;

(i.e., hold a copy, not a reference). After this, you should be fine.

Hope this helps,
-shez-

const string& getName(){retur n name;}
};

class Dog : public Animal {
public:
Dog(const string& n):Animal(n){}
virtual ~Dog(){}
virtual void speak(){
cout << "Woof. I am " << getName() << endl;
};
};

class Zoo {
public:
set<Dog*> dogs;
void addAnimal(Anima l* a){
Dog* d;
if((d = dynamic_cast<Do g*>(a))){
dogs.insert(d);
}else throw runtime_error(" Unknown animal");
}
};

int main(){
Zoo zoo;
Dog d1("Rex");
Dog d2("Rox");
zoo.addAnimal(& d1);
zoo.addAnimal(& d2);
for(set<Dog*>:: iterator it = zoo.dogs.begin( ); it !=
zoo.dogs.end(); ++it){
(*it)->speak();
}
}

// (I know that zoo::dogs should be private, I just made it public
here to make code shorter)

Thanks for your comments!
Markus


Jul 23 '05 #4
Thomas Maier-Komor wrote:


you pass "Rex" and "Rox" to Dog::Dog(const string &) which
create a temporary string. g++ does not seem to find out
that this temporary is needed until d1 and d2 go out of scope.
I would say this is a bug in g++, as Sun's Studio compiler does
what you would expect it to do...

Tom


OK, I looked into the standard and it says that the temporary
may be destructed after the execution of the ctor. So g++ does
the right thing. Simply create a string variable and pass it
to the Dog constructor and you will be fine. As an alternative
you can change Animal::name to a normal variable (not a reference)
and everything will be OK, too. This has the advantage that
you don't have to bother around with the lifetime of the string
you pass to the constructor...

Tom
Jul 23 '05 #5
Change this to:

const string name;

(i.e., hold a copy, not a reference). After this, you should be fine.
Hope this helps,
-shez-

Can you really do that, copy the temp? let's say:

char * p="temp"; // changing anything in p is an error
char arr[5];
strpcpy(p,arr);

what is the storaga nature of above temp?

Jul 23 '05 #6
puzzlecracker wrote:
Change this to:

const string name;

(i.e., hold a copy, not a reference). After this, you should be
fine.
Hope this helps,
-shez-


Can you really do that, copy the temp? let's say:

Sure, why not. The temp stays around long enough for name to get
initialized. String doesn't care what the char* it's initialized is
as long as it:
1. Is null terminated (or you pass the length)
2. It's valid while the consturctor is running.
char * p="temp"; // changing anything in p is an error
char arr[5];
strpcpy(p,arr);

Why would you want to do this?
Jul 23 '05 #7
puzzlecracker wrote:
Change this to:

const string name;

(i.e., hold a copy, not a reference). After this, you should be fine.

Hope this helps,
-shez-

Can you really do that, copy the temp?

Sure, why not?
The temporary gets destroyed long after the copy has been made.
let's say:

char * p="temp"; // changing anything in p is an error
char arr[5];
strpcpy(p,arr);
that's completely different.
No temporary is involved.

what is the storaga nature of above temp?


There is no temporary.
If you are referring to "temp" in the above. This
is a string literal which gets created at the beginning
of your program and it lifes on until the program shuts
down. A completely different case.

--
Karl Heinz Buchegger
kb******@gascad .at
Jul 23 '05 #8

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

Similar topics

13
4979
by: GianGuz | last post by:
Everyone knows about the complex and cpu-expensive procedures taken by dynamic_cast to find the right function call in a virtual classes hierarchy. The question I would to rise is when dynamic_cast is really necessary? A wise usage of templates and/or non dynamic_cast operators can grant the compiler with any information it needs to understand at compile time what is the right method to call. In the following example I tested the usage of...
3
1999
by: Axter | last post by:
I'm wondering about the practical use of dynamic_cast in reusable or generic code. I'm currently working on a smart pointer that can be used on vector and other STL containers. See following link: http://code.axter.com/arr_ptr.h In above code, there's a function called clone_func_ptr_interface within the func_ptr_holder class. In this function, I need to cast from a base pointer to a derived
1
1534
by: Steven T. Hatton | last post by:
The result shown below doesn't surprise me now. But it did several months ago when I followed some bad advice and tried to check if I had a live object at the address referenced by a pointer. Can I assume the result is consistente with the Standard? Tue May 10 21:24:24:> cat foo.cc #include <iostream> struct Foo{virtual ~Foo(){} }; struct Bar{virtual ~Bar(){} }; int main(){
3
2540
by: Ganesh | last post by:
On devx site, I saw following code. It says when a derived class is tried to cast to base type, it looks at the missing vtable and complains if the object is already deleted. I am of the opinion that this doesnt work if the destructor is not virtual or when the class has no virtual members. I would like to know is there anything wrong in what I am thinking. (I agree it is better to keep base class dtor as virtual, but supposing it is not...
5
2041
by: tthunder | last post by:
Hi @all, Perhaps some of you know my problem, but I had to start a new thread. The old one started to become very very confusing. Here clean code (which compiles well with my BCB 6.0 compiler). You can find a problem there, which cannot be solved by dynamic_cast, because the pointers can be NULL, and I only want to know, if the pointer type is derived from another pointer type. BTW: I cannot create a temporary instance, because used...
22
4817
by: Boris | last post by:
I'm porting code from Windows to UNIX and ran into a problem with dynamic_cast. Imagine a class hierarchy with three levels: class Level2 derives from Level1 which derives from Base. If you look now at this code: Base *b = new Level2(); Level1 *l1 = dynamic_cast<Level1*>(b); Should dynamic_cast return a valid pointer or 0? I wonder as Visual Studio 2005 returns a valid pointer while g++ 3.4.6 returns 0. Both compilers work as expected...
15
2829
by: Grizlyk | last post by:
Hello. Returning to question of manual class type identification, tell me, for ordinary inheritance is C++ garantee that dynamic_cast<Derived*>(Base*) can be implemented similarly to return (Base*->type_fild >= Derived_typeid)? Base*: 0;
25
3145
by: lovecreatesbea... | last post by:
Suppose I have the following three classes, GrandBase <-- Base <-- Child <-- GrandChild The following cast expression holds true only if pBase points object of type of ``Child'' or ``GrandChild'', i.e. types not upper than Child in the above class hierarchy, dynamic_cast<Child*>pBase
18
5290
by: Eric | last post by:
Ok...this seems to be treading into some really esoteric areas of c++. I will do my best to explain this issue, but I don't fully understand what is happening myself. I am hoping that the problem comes down to standard c++ stuff and is not specific to Mac OS X compiler&linker. I have put together a simple test project which can be found at: http://ericgorr.net/LibraryLoading.zip which demonstrates the problem.
0
10793
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10548
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10219
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7758
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6954
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5794
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4427
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3978
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3081
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.