Segmentation fault while using const_cast to overload a constant function - c++

I'm having some problems with the const_cast function. I created a class Calorimeter that consists of a CaloGrid and some other stuff. I have to overload the grid() function to return the CaloGrid belonging to the class Calorimeter, however calling the main function returns a segmentation fault.
I know that using const_cast is not the best practice, but for this assignment I have to use it. Simply duplicating the code for the const CaloGrid& grid() const for the non-constant function would probably work.
What am I doing wrong? Is there a better way of doing this? And what is the point of overloading the function with a const copy of the function?
main.cpp
/*headers*/
int main() {
// create 2x2 Calorimeter object
Calorimeter C(2,2);
// return the CaloGrid class from this object
C.grid();
// gives segmentation error
}
Calorimeter.cpp
/*headers*/
// Calorimeter is object with CaloGrid of dimensions nx by ny
Calorimeter::Calorimeter(int nx,int ny){
// initalize the grid and allocate memory
Cgrid = new CaloGrid(nx,ny);
}
Calorimeter::~Calorimeter(){
// delete memory
delete Cgrid;
}
// return the grid
const CaloGrid& Calorimeter::grid() const{
return *Cgrid;
}
// segmentation error
CaloGrid& Calorimeter::grid(){
return const_cast<CaloGrid&> (Calorimeter::grid());
}
Calorimeter.hh
#ifndef CALORIMETER_HH
#define CALORIMETER_HH
class Calorimeter {
public: // Interface
Calorimeter(int,int);
~Calorimeter();
const CaloGrid& grid() const;
CaloGrid& grid();
private: // Implementation
CaloGrid *Cgrid;
}
#endif

In
return const_cast<CaloGrid&> (Calorimeter::grid());
You are infinitly calling grid(). Since the grid function is non const Calorimeter::grid() will call the non const version of the function again, which calls the non const version again which, well, you get the point.
If you want to call the const version of the function then you need to cast this to const. You can do that with
const_cast<const Calorimeter&>(*this)
So with that your full code would look like
return const_cast<CaloGrid&>(const_cast<const Calorimeter&>(*this).grid());
If it doesn't look right it is probably the tears getting in your eyes from the code.

Here's your class method:
CaloGrid& Calorimeter::grid(){
What does it do? Well:
return const_cast<CaloGrid&> (Calorimeter::grid());
It calls Calorimeter::grid(), and applies const_cast to its return value? What does this Calorimeter::grid() do? See above.
The issue of what const_cast does, and whether or not it's the right thing to do is irrelevant. This class method calls itself, resulting in infinite recursion, and your program blows quickly, as it runs out of its operating system-allotted stack space.
Although it's not quite clear what you're trying to do here, the answer as to the reason of your segfault is quite simple: infinite recursion.
The recursive call does not invoke the other, overloaded, const class method. This is being called from a mutable class method, so it picks the mutable overload, again.

Expanding on the other posts, you may want to consider writing it this way:
#include <memory>
struct CaloGrid {
CaloGrid(int x, int y) {};
};
class Calorimeter {
public: // Interface
Calorimeter(int,int);
// no destructor - it's not necessary
const CaloGrid& grid() const;
CaloGrid& grid();
private: // Implementation
// resources managed automatically
std::unique_ptr<CaloGrid> Cgrid;
};
// Calorimeter is object with CaloGrid of dimensions nx by ny
Calorimeter::Calorimeter(int nx,int ny)
: Cgrid { std::make_unique<CaloGrid>(nx, ny) }
{
}
// return the grid
const CaloGrid& Calorimeter::grid() const{
return *Cgrid;
}
// no error any more
CaloGrid& Calorimeter::grid(){
return *Cgrid;
}
int main() {
// create 2x2 Calorimeter object
// now we can use move-construction
auto C = Calorimeter(2,2);
// return the CaloGrid class from this object
C.grid();
}
The raw pointer has been replaced with a smart pointer. This gives us (at least) 2 advantages:
Resource management is automated, so we can't forget to delete the CaloGrid, or accidentally delete it twice.
Calorimeter inherits the copy/move capabilities of the smart pointer (in this case, dangerous unwanted copies are disallowed but we get to keep moves and move-assignments)
Furthermore, although the grid method now repeats code, it repeats trivial code. The class has become much easier to both use correctly and maintain.

What you need is the following
CaloGrid & Calorimeter::grid()
{
return const_cast<CaloGrid &>(const_cast<const Calorimeter *>(this)->grid());
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Otherwise the non-constant member function grid is recursively calls itself.

I'm having some problems with the const_cast function.
It's an operator, not a function.
I know that using const_cast is not the best practice,
It is bad practice if you design your code's architecture such that const_cast cannot be avoided. It can be an acceptable real-life workaround if const correctness has already been violated elsewhere (e.g. in libraries you have to use, although well-designed libraries do not suffer from such shortcomings).
but for this assignment I have to use it.
Says who?
Simply duplicating the code for the const CaloGrid& grid() const for the non-constant function would probably work.
Yes, and it would be best practice. Just do it.
What am I doing wrong?
You've been a bit too eager to apply the DRY (Don't Repeat Yourself) principle. This has made you write code which has accidentally caused the infinite recursion problem explained by Sam in the other answer.
And what is the point of overloading the function with a const copy of the function?
The const overload allows you to call the function on a Calorimeter const object.
It's like std::vector::operator[], just to name a prominent example. Operations like that often come in const/non-const pairs.
You can look up how your compiler implements std::vector::operator[]. There's a good chance it will just duplicate the tiny piece of code necessary and not use const_cast or other tricks.
By the way...
It may not be a good idea to have a function like grid() in the first place. It practically makes the private data member public.

Related

const access and non-const access

I have a class which internally owns a vector of foo
class bar {
private:
vector<Foo> foos_;
}
Now I want to design public access to this vector. I am thinking of two versions of the function:
Foo& getFoo(int index) {
// first do size checking, return ref
return foos[index];
}
and
const Foo& getFoo(int index) const {
// first do size checking, return const reference
return foos[index];
}
Any downside of this approach? One obvious downside is I copy the almost identical code simply twice. Is there a better way to do this?
----- edit -----
the second accessor forgets const, updated
Having both const and non-const accessors is somewhat common in C++. There is no language feature to combine the code for both--you really do need to write it twice.
By the way, you don't need to do bounds checking yourself, you can use foos_.at(index) instead of foos_[index] and then you'll have automatic bounds checking.

C++11 best practice to use rvalue

I am new to C++11. In fact until recently, I programmed only using dynamic allocation, in a way similar to Java, e.g.
void some_function(A *a){
a->changeInternalState();
}
A *a = new A();
some_function(a);
delete a;
// example 2
some_function( new A() ); // suppose there is **no** memory leak.
Now I want to reproduce similar code with C++11, but without pointers.
I need to be able to pass newly created class class A directly to function useA(). There seems to be a problem if I want to do so with non-const normal reference and It works if I do it with rvalue reference.
Here is the code:
#include <stdio.h>
class A{
public:
void print(){
++p; // e.g. change internal state
printf("%d\n", p);
}
int p;
};
// normal reference
void useA(A & x){
x.print();
}
// rvalue reference
void useA(A && x){
useA(x);
}
int main(int argc, char** argv)
{
useA( A{45} ); // <--- newly created class
A b{20};
useA(b);
return 0;
}
It compiles and executes correctly, but I am not sure, if this is the correct acceptable way to do the work?
Are there some best practices for this kind of operations?
Normally you would not design the code so that a temporary object gets modified. Then you would write your print function as:
void useA(A const & x){
x.print();
}
and declare A::print as const. This binds to both rvalues and lvalues. You can use mutable for class member variables which might change value but without the object logically changing state.
Another plan is to keep just A &, but write:
{ A temp{45}; useA(temp); }
If you really do want to modify a temporary object, you can write the pair of lvalue and rvalue overloads as you have done in your question. I believe this is acceptable practice for that case.
The best thing about C++11 move semantics is that most of the time, you get them "for free" without having to explicitly add any &&s or std::move()s in your code. Usually, you only need to use these things explicitly if you're writing code that does manual memory management, such as the implementation of a smart pointer or a container class, where you would have had to write a custom destructor and copy constructor anyway.
In your example, A is just an int. For ints, a move is no different from a copy, because there's no opportunity for optimization even if the int happens to be a disposable temporary. Just provide a single useA() function that takes an ordinary reference. It'll have the same behavior.

Overloading operator [] for both read and write

I'm having a trouble overloading operator [] for both read and write in my objects. This is a large code with different components and I'm not going to put all the details here since it wont help. In a nutshell what I have is the following
class MyObject(){
inline SetterProxy& operator[](int i) {
SetterProxy a(i);
return a;
}
inline double operator[](int i) const{
return some_value;
}
}
The first overloaded [] works fine for assigning values (if you are wondering what the SetterProxy is, I have to use Proxy classes to be able to do some checking and internal function calls before assigning values). However, the second one which should supposedly be called when reading does not work and the code crashes. I'm not sure what is happening here but when I comment out the first one it just works fine! Could it be that compiler somehow confuses the two since they are both inline?
Any thought would be appreciated.
EDIT:
Ok here is the SetterProxy itself:
class SetterProxy{
private:
Vec v;
int i;
double *ptr_val;
public:
inline SetterProxy(Vec v_, int i_) {
v = v_;
i = i_;
VecGetArray(v,&ptr_val);
}
inline ~SetterProxy(){
VecRestoreArray(v,&ptr_val);
}
inline void operator=(double rhs ){
ptr_val[i] = rhs;
}
};
Although I dont think its coming directly from that. Also initially I had it to return by value and I though changing it to reference would be more efficient. I think this should be safe since the assignment is done in the Proxy operator=() class and after that the proxy class goes out of scope. Either way, that does not save my problem!
You're returning a reference to a local variable - it goes out of scope when the operator returns, leaving your reference dangling. A good compiler should warn you about this if you turn the warning setting up to a reasonable level.
As noted in #Stuart Golodetz's answer, you are returning a reference to SetterProxy referring to a, which is local to your method and thus goes out of scope when it returns.
You should instead return a SetterProxy instance by value: that shouldn't be a big deal, SetterProxy will probably just hold the index and a reference to the "parent" object, so the compiler-generated copy constructor for it will be fine and the copy won't be costly at all.
By the way, unless you want to allow negative indexes, the usual idiom is to use size_t for indexes in arrays.

Swap method with const members

I want to implement a Swap() method for my class (let's call it A) to make copy-and-swap operator=(). As far as I know, swap method should be implemented by swapping all members of the class, for example:
class A
{
public:
void swap(A& rhv)
{
std::swap(x, rhv.x);
std::swap(y, rhv.y);
std::swap(z, rhv.z);
}
private:
int x,y,z;
};
But what should I do if I have a const member? I can't call std::swap for it, so I can't code A::Swap().
EDIT: Actually my class is little bit more complicated. I want to Serialize and Deserialize it. Const member is a piece of data that won't change (its ID for example) within this object. So I was thinking of writing something like:
class A
{
public:
void Serialize(FILE* file) const
{
fwrite(&read_a, 1, sizeof(read_a), file);
}
void Deserialize(FILE* file) const
{
size_t read_a;
fread(&read_a, 1, sizeof(read_a), file);
A tmp(read_a);
this->Swap(tmp);
}
private:
const size_t a;
};
and call this code:
A a;
FILE* f = fopen(...);
a.Deserialize(f);
I'm sorry for such vague wording.
I think what you really want is to have an internal data structure that you can easily exchange between objects. For example:
class A
{
private:
struct A_Data {
int x;
int y;
const int z;
A_Data(int initial_z) : z(initial_z) {}
};
std::auto_ptr<A_Data> p_data;
public:
A(int initial_z) : p_data(new A_Data(initial_z)) {}
void swap(A& rhv) {
std::swap(p_data, rhv.p_data);
}
};
This keeps the z value constant within any instance of A object internal data, but you can swap the internal data of two A objects (including the constant z value) without violating const-correctness.
After a good nights sleep I think the best answer is to use a non-const pointer to a const value -- after all these are the semantics you are trying to capture.
f0b0s, a good design principle is to design your objects to be immutable. This means that the object can't change once created. To "change" the object, you must copy the object and make sure to change the elements you want.
That being said, in this case you should look at using a copy constructor instead to copy the objects you want to swap, and then actually swap the references to the object. I can understand it'd be tempting just to be able to change the elements of an object under the hood, but it'd be better to make a copy of the object and replace the references to that object with the NEW object instead. This gets you around any const nastiness.
Hope this helps.
I suggest you use pointers to the instances. The pointers can be swapped much easier than the data in the class or struct.
The only way to swap a constant value is to create another object, or clone the current object.
Given a struct:
struct My_Struct
{
const unsigned int ID;
std::string name;
My_Struct(unsigned int new_id)
: ID(new_id)
{ ; }
};
My understanding is that you want to swap instances of something like My_Struct above. You can copy the mutable (non-const) members but not the const member. The only method to alter the const member is to create a new instance with a new value for the const member.
Perhaps you need to rethink your design.
IMHO you must consider not to swap CONST members.
PD: I think you could consider to use reflection in your approach. so you don't have to maintain the function.
This is why const_cast was created. Just remember not to shoot your foot off.
Edit: OK, I concede - const_cast wasn't made for this problem at all. This might work with your compiler, but you can't count on it and if demons come flying out of your nostrils, please don't blame me.
tl;dr; : It's Undefined Behavior.
Reference/reason: CppCon 2017: Scott Schurr “Type Punning in C++17: Avoiding Pun-defined Behavior, #24m52s +- ”
My interpretation, by example:
Suppose you create an object of type T, which have some const members. You can pass this object as a non-const reference to a function f(&T) that manipulates it, but you'd expect the const members to remain unalterable after the call. swap can be called in non-const references, and it can happen inside the function f, breaking the premise of const members to the caller.
Every part of your code that uses swap would have to assert that the object of type T being swapped does not belong to any context where the const members are assumed constant. That is impossible to automatically verify*.
*I just assumed that this is impossible to verify because it seems like an extension of the undecidability of the halting problem.

auto_ptr question in c++

I am new here.
I am also new on C++
So here is the class and function i wrote.But i got the compiler error
My class:
class fooPlayer
{
public:
void fooPlayerfunc(){}//doing something here
char askYesNo(std::string question);
};
class fooPlayerFactory
{
public:
virtual std::auto_ptr<fooPlayer> MakePlayerX() const;
virtual std::auto_ptr<fooPlayer> MakePlayerO() const;
private:
std::auto_ptr<fooPlayer> MakePlayer(char letter) const;
std::auto_ptr<fooPlayer> my_player;
};
Implement my class:
auto_ptr<fooPlayer> fooPlayerFactory:: MakePlayer(char letter) const
{
my_player->fooPlayerfunc();
return my_player;
}
auto_ptr<fooPlayer> fooPlayerFactory::MakePlayerX() const
{
char go_first = my_player->askYesNo("Do you require the first move?");
MakePlayer(go_first);
return my_player;
}
auto_ptr<fooPlayer> fooPlayerFactory::MakePlayerO() const
{
return my_player;
}
My main() function here:
int main()
{
fooPlayerFactory factory;
factory.MakePlayerX();
factory.MakePlayerO();
}
I got the error:
error C2558: class 'std::auto_ptr<_Ty>' : no copy constructor available or copy constructor is declared 'explicit'
I do not know how to change it even after reading the document on this link:
The reason for the error is that you are calling the copy constructor of auto_ptr my_player in fooPlayerFactory::MakePlayerO() which is a const method. That means that is cannot modify its members.
However the copy constructor of auto_ptr DOES modify the right hand side so returning my_player trys to change its pointer to 0 (NULL), while assigning the original pointer to the auto_ptr in the return value.
The signature of the copy constuctor is
auto_ptr<T>::auto_ptr<T>(auto_ptr<T> & rhs)
not
auto_ptr<T>::auto_ptr<T>(const auto_ptr<T> & rhs)
The copy constructor of auto_ptr assigns ownership of the pointer to the left hand side, the right hand side then holds nothing.
I don't think you want to use auto_ptr here, you probably want boost::smart_ptr
It looks like you have mixed up two uses for auto_ptr
The first is as poor man's boost::scoped_ptr. This is to manage a single instance of a pointer in a class, the class manages the life time of the pointer. In this case you don't normally return this pointer outside your class (you can it is legal, but boost::smart_ptr / boost::weak_ptr would be better so clients can participate the life time of the pointer)
The second is its main purpose which is to return a newly created pointer to the caller of a function in an exception safe way.
eg
auto_ptr<T> foo() {
return new T;
}
void bar() {
auto_ptr<T> t = foo();
}
As I said I think you have mixed these two uses auto_ptr is a subtle beast you should read the auto_ptr docs carefully. It is also covered very well in Effective STL by Scott Meyers.
In your code:
auto_ptr<fooPlayer> fooPlayerFactory:: MakePlayer(char letter) const
{
my_player->fooPlayerfunc();
return my_player;
}
This is a const function, but fooPlayerfunc is not const - my compiler reports this error rather than the one you say you are getting. Are you posting the real code?
I don't think you actually want to constructing dynamic objects here.
A factory object creates and returns an object it normally does not keep a reference to it after creation (unless you are sharing it), and I don't actually see anywhere that you are creating the player.
If you only ever create one player internally in your (fooPlayerFactory). Then create an object and return references to it.
Edit: in response to the comment (which is correct, my bad), I left only the advice part.
Best practice is to have the factory methods just return a plain old pointer to the underlying object, and let the caller decide how to manage ownership (auto_ptr, scoped_ptr, or whatever).
Also your code is buggy, any class that implements virtual methods should have a virtual destructor.
I'm not seeing anywhere you construct my_player, so I have a feeling that some of the code is missing. Specifically, I think your constructor has this line:
my_player = new fooPlayer()
A fooPlayer object is not quite the same thing as an auto_ptr<fooPlayer> object, and auto_ptr is intentionally designed to prevent assigning from one to the other because, frankly, the alternative is worse. For the details, look up (1) conversion constructors, (2) the explicit keyword, and (3) copy constructors and destructive copy semantics.
You should change the constructor to either:
class fooPlayerFactory {
public:
fooPlayerFactory()
{
my_player = std::auto_ptr<fooPlayer>(new fooPlayer());
}
Or (using a member initializer list):
class fooPlayerFactory {
public:
fooPlayerFactory() : my_player(std::auto_ptr<fooPlayer>(new fooPlayer()) { }
The solution isn't pretty but, like I said, the alternative is worse due to some really arcane details.
As a bit of advice, though, you're making life harder than it needs to be; and may in fact be causing strange bugs. auto_ptr exists to manage the lifetime of an object, but the only reason you need to worry about the lifetime of my_player is that you've allocated it with new. But there's no need to call new, and in fact there's no need to keep my_player. And unless fooPlayerFactory is meant to be the base class for some other factory, there's no need to mark functions virtual.
Originally I thought you could get away with simply returning copies of the my_player object, but there's a problem: before returning my_player from MakePlayer() you call a method on it, and I assume that method changes the internal state of my_player. Further calls to MakePlayer() will change the state again, and I think you're going to eventually have my_player in the wrong state. Instead, return a different fooPlayer object with each request. Don't do memory management, just promise to construct the object. That way the user can decide on memory allocation:
fooPlayerFaclotry factory;
fooPlayer on_stack = factory.MakePlayerX();
fooPlayer* on_heap_raw_pointer = new fooPlayer(factory.MakePlayerO());
std::auto_ptr<fooPlayer> on_heap_managed_scope
= std::auto_ptr<fooPlayer>(factory.MakePlayerX());
I would change fooPlayerFactory to look like this:
class fooPlayerFactory
{
private:
fooPlayer MakePlayer(const char letter) const
{
fooPlayer result;
result.fooPlayerfunc();
return result;
}
public:
fooPlayer* MakePlayerX() const
{
char go_first = askYesNo("Do you require the first move?");
return MakePlayer(go_first);
}
fooPlayer MakePlayerO() const
{
return fooPlayer();
}
};