I have a problem with polymorphism in a C++ project I'm working on. I have a base class named State, and a derived TestState class. I'm trying to call a virtual function overidden in the derived class from a State pointer. The virtual function is called, but when deleting the pointer I get the following error:
Invalid address specified to RtlValidateHeap( 00FF0000, 0018FD74 )
After searching for other answers I've been able to understand that this means that the heap is corrupted, but none of the solutions I've found have worked for me.
This is the code I'm running:
int main()
{
TestState test;
State *state = new State();
state = &test;
state->Init();
delete state;
}
State.h
#pragma once
#include <iostream>
class State
{
public:
State();
virtual ~State();
virtual void Init();
virtual void Reinit();
virtual void Deinit();
};
State.cpp
#include "State.h"
State::State()
{
}
State::~State()
{
std::cout << "Destroying State!" << std::endl;
}
void State::Init()
{
std::cout << "Initialized State!" << std::endl;
}
void State::Deinit()
{
}
void State::Reinit()
{
}
TestState.h
#pragma once
#include "State.h"
#include <iostream>
class TestState : public State
{
public:
TestState();
~TestState();
void Init();
void Deinit();
void Reinit();
};
TestState.cpp
#include "TestState.h"
TestState::TestState()
{
}
TestState::~TestState()
{
std::cout << "Destroying TestState!" << std::endl;
}
void TestState::Init()
{
std::cout << "Initialized TestState!" << std::endl;
}
void TestState::Deinit()
{
}
void TestState::Reinit()
{
}
The destructor of both State and TestState are called when the pointer is deleted.
Thanks in advance.
Because you are deleting something in the stack. When you assign the pointer to a reference to a local variable you assign the pointer to an entity allocated in the stack. It cannot be delete using "delete" which is for heap variables. In addition you are leaking what you allocated with the new.
TestState test;
State *state = new State();
state = &test; //Now it points to the test which is in the stack
state->Init();
delete state; //Delete something in the stack. Not good.
Something like this should work better.
TestState test;
State *state = &test;
state->Init();
Even though the solution to your specific problem was easy (i.e. you were trying to delete a stack-allocated variable as if it was heap-allocated), I wanted to post my solution to my mysterious RtlValidateHeap assertion.
It turns out that the code I was working on had mixed settings between projects for "Runtime library" (in the project properties, under C/C++ -> Code Generation). The application has "Multithreaded Debug", the DLLs had "Multithreaded Debug DLL". They all need to be set to the same thing.
If you mix DLL and non-DLL runtime libraries, you end up with two separate heaps, and it becomes impossible to delete an object allocated under one runtime-library from code using another runtime-library. You end up with mysterious RtlValidateHeap assertions.
Hope this helps someone else.
This is what shared pointers are for :) There is a very good Smart Pointer video by The Cherno on youtube.
This should fix things change your main to this:
#include "TestState.h"
#include "State.h"
#include <memory>
int main()
{
{
std::shared_ptr<TestState> test = std::make_shared<TestState>();
std::shared_ptr<TestState> state = test;
state->Init();
}
//delete state;
}
Related
I am trying to use the boost::signals2 functionalities in my program.
In my "Main Class" called "Solid" I have a member which I initialize inside the constructor body (so after the member initializer list) like this:
pointer_M = boost::make_shared<OtherClass>(/*parameters,...*/);
If the signal is triggered by some function I do not want to call a member of "OtherClass" (to which pointer_M points) but a member from "Solid", i.e. the class which initialized pointer_M just.
I tried the following:
boost::signals2::connection tria_signal = /*...*/.connect( boost::signals2::signal<void()>::slot_type(&Solid::call_this_function, pointer_M.get()).track(pointer_M) );
"call_this_function" is a member function of Solid. Unfortunately there are a bunch of error messages. "OtherClass" and "Solid" are not related by inheritance.
I would appreciated getting some advice how to fix my issue since I am very unexperienced with boost.
Best
But is that what I am trying to achieve possible at all?
The point is we can't tell without a clearer description. It sure sounds like a no-brainer: signals are specifically used to decouple callers and callees.
So let me just make up your "dummycode" for you. I'm going to sidestep the enormous type-overcomplication that you showed in that line:
boost::signals2::connection tria_signal =
/*...*/.connect(boost::signals2::signal<void()>::slot_type(
&Solid::call_this_function, pointer_M.get())
.track(pointer_M));
The whole idea of slots is that they generalize callables using type erasure. Just provide your callable in any compatible form and let the library deduce the arcane implementation types.
Live On Coliru
#include <boost/signals2.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
struct OtherClass {
OtherClass(...) {}
boost::signals2::signal<void()> tria;
void test() {
if (!tria.empty())
tria();
}
};
struct Solid {
boost::shared_ptr<OtherClass> pointer_M;
Solid() {
pointer_M = boost::make_shared<OtherClass>(1,2,3);
auto tria_signal = pointer_M->tria.connect(
boost::bind(&Solid::call_this_function, this));
}
private:
void call_this_function() {
std::cout << "Solid was here" << std::endl;
};
};
int main() {
Solid s;
s.pointer_M->test();
}
Prints
Solid was here
Crystal Ball: Can We Guess The Problem?
Maybe we can guess the problem: it looked like you were putting effort into tracking the lifetime of the object pointed to by pointer_M. That's not useful, since that OtherClass owns the signal in the first place, meaning that all connections are disconnected anyways when the OtherClass disappears.
Correct Lifetime Management
What you likely want is for the connection to disconnect when the lifetime of the Solid object ends, not the OtherClass. In general, I'd suggest using scoped_connection here:
Live On Coliru
#include <boost/signals2.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
struct OtherClass {
OtherClass(...) {}
boost::signals2::signal<void()> tria;
void test() {
if (!tria.empty())
tria();
}
};
struct Solid {
boost::shared_ptr<OtherClass> pointer_M;
Solid() {
pointer_M = boost::make_shared<OtherClass>(1,2,3);
tria_signal = pointer_M->tria.connect(
boost::bind(&Solid::call_this_function, this));
}
private:
boost::signals2::scoped_connection tria_signal;
void call_this_function() {
std::cout << "Solid was here" << std::endl;
};
};
int main() {
boost::shared_ptr<OtherClass> keep;
{
Solid s;
std::cout << "Testing once:" << std::endl;
s.pointer_M->test();
keep = s.pointer_M; // keep the OtherClass alive
} // destructs Solid s
std::cout << "Testing again:" << std::endl;
keep->test(); // no longer connected, due to scoped_connection
}
Prints
Testing once:
Solid was here
Testing again:
Simplify
In your case, the OtherClass is already owned by the Solid (at least it is created). It seems likely that having the shared-pointer is not necessary here at all:
Live On Coliru
#include <boost/signals2.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
struct OtherClass {
OtherClass(...) {}
boost::signals2::signal<void()> tria;
void test() {
if (!tria.empty())
tria();
}
};
struct Solid {
Solid() : oc_M(1,2,3) {
tria_signal = oc_M.tria.connect(
boost::bind(&Solid::call_this_function, this));
}
void test() { oc_M.test(); }
private:
OtherClass oc_M;
boost::signals2::scoped_connection tria_signal;
void call_this_function() {
std::cout << "Solid was here" << std::endl;
};
};
int main() {
Solid s;
s.test();
}
Because the members are destructed in reverse order of declaration, this is completely safe.
Architecture Astronauting
If you know what you're doing, and the pointer_M actually needs to be shared, then likely you want to track that pointer. You should probably be considering making Solid also enable_shared_from_this. If you want to be really "Enterprise Grade Engineerâ„¢" about it, you could perhaps do something fancy with the aliasing constructor: What is shared_ptr's aliasing constructor for?
How can such a code work correctly when the IWindow pointer clearly has an address to a ISheet class which has no method Say?
#include <iostream>
using namespace std;
class IWindow
{
private:
int p;
double f;
public:
void Say() { cout << "Say in IWindow"; }
};
class ISheet
{
public:
void foo() { cout << "ISheet::foo"; }
};
int main()
{
ISheet *sh = new ISheet();
int ptr = (int)sh;
IWindow *w = (IWindow*)ptr;
w->Say();
sh->foo();
return 0;
}
When compiled in Visual Studio 2015 it runs and executes with no problems, but I was expecting to get an error on line w->Say(). How is this possible?
It works by the grace of the almighty Undefined Behavior. Your functions don't try to access any data members of the containing class, they just write something to std::cout, which anyone can do.
What you've effectively done is
#include <iostream>
void IWindow_Say(void*)
{
std::cout << "Say in IWindow";
}
int main()
{
IWindow_Say(0xdeadbeef); // good luck with that pointer
}
You never used the pointer (which became this in your original example) so no side-effects were observed.
Shared pointer is working without assign memory to Win class.
Code:
class Win
{
public:
void disp()
{
//Do something
}
};
int main()
{
std::shared_ptr<Win> sharedptr;///holds null pointer
sharedptr->disp();//// why its working
}
Why it's calling above function without assign memory to it. Could someone help me out of this?
Try to do it like this:
#include <memory>
#include <iostream>
class Win
{
public:
void disp(){std::cout << x;}
int x=5;
};
int main()
{
std::shared_ptr<Win> sharedptr;///holds null pointer
sharedptr->disp();//// why its working
}
You will not get 5. You may get anything. Like the guys in the comments said, it is undefined behaviour .
Here's a minimal example of a problem that I'm having, and I can't work out how I should solve it:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(Thing*);
};
void App::add_thing(Thing* thing) {
thingVec.push_back(std::unique_ptr<Thing>(thing));
}
int main() {
App app;
Thing thing;
app.add_thing(&thing);
}
This compiles and runs with no issues, however, upon reaching the end of main, segfaults and spits out:
Error in `/path/testapp': free(): invalid pointer: 0x00007fff97118070 ***
Any possible help? The reason I want to store (unique) pointers is that Thing will usually be derived.
EDIT:
One working solution:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(Thing*);
};
void App::add_thing(Thing* thing) {
thingVec.push_back(std::unique_ptr<Thing>(thing));
}
int main() {
App app;
Thing* thing = new Thing;
app.add_thing(thing);
}
But from what I understand, I should be able to avoid using new entirely, and use make_unique? I can't seem to find where make_unique is actually defined though.
EDIT 2:
Is this more appropriate? Is there a less messy looking way to do this? Otherwise, it works well.
#include <vector>
#include <memory>
#include <iostream>
class Thing {
public:
int foo = 42;
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(std::unique_ptr<Thing>);
};
void App::add_thing(std::unique_ptr<Thing> thing) {
thingVec.push_back(std::move(thing));
}
int main() {
App app;
app.add_thing(std::unique_ptr<Thing>(new Thing()));
std::cout << app.thingVec.back()->foo << std::endl;
}
Because I may end up with lines like
app.thingVex.back()->barVec.back()->blahMap.emplace("flop", std::unique_ptr<Tree>(new Tree));
std::unique_ptr is attempting to delete a stack-allocated Thing instance.
Your error is essentially in the lines:
Thing thing;
app.add_thing(&thing);
The interface to add_thing is wrong because it takes a "non-owning" raw pointer to a Thing and then assumes that it can take full ownership of the object passed in by constructing a unique_ptr from it.
If you change add_thing to take a unique_ptr<Thing> by value, then the caller will be prevented from implicitly converting a raw pointer and will no that they need to construct a new unique_ptr to a heap allocated thing into the add_thing function.
e.g.
void App::add_thing(std::unique_ptr<Thing> thing) {
thingVec.push_back(std::move(thing));
}
int main() {
App app;
app.add_thing(std::make_unique<Thing>());
}
(Note that std::make_unique is a future feature; std::unique_ptr<Thing>(new Thing) works now.)
You should pass local object to unique_ptr.
Replace
Thing thing;
app.add_thing(&thing);
with
app.add_thing(new Thing);
If you want to also edit the object
Thing *thing = new Thing;
// thing->some_val = val;
app.add_thing(thing);
Make sure not to add the same object twice in the app, as std::unique_ptr take the ownership of pointer pointer would be tried to free more than 1 time.
You are transferring the ownership not properly. You might utilize a shared pointer with a custom deleter to the prevent deletion of the referenced variable:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::shared_ptr<Thing>> thingVec;
void add_thing(std::shared_ptr<Thing>&& thing) {
thingVec.push_back(std::move(thing));
}
};
template<typename T>
inline std::shared_ptr<T> make_no_delete(T& value)
{
return std::shared_ptr<T>(&value, [](void*){});
}
int main() {
App app;
Thing thing;
// Add without transferring ownership:
app.add_thing(make_no_delete(thing));
// Add and transfer ownership:
app.add_thing(std::make_shared<Thing>());
}
Before I present the code which is found at the bottom of this post I would like to talk about the issue and the fix's that I do not desire. Okay basically I've created a GUI from scratch sort of and one requirement I wanted for this was allow components to have their own click executions so if i click a button or tab etc.. It would call Component->Execute(); Well normally you would do something like a switch statement of ids and if that components ID equaled n number then it would perform this action. Well that seemed kinda dumb to me and I thought there has to be a better way. I eventually tried to incorporate a feature in JAVA where you would do like Component.AddActionListener(new ActionListener( public void execute(ActionEvent ae) { })); or something like that and I thought that this feature has to be possible in C++. I eventually came across storing void functions into a variable in which could be executed at any time and modified at any time. However I hadn't noticed an issue and that was this only worked with static functions. So below you'll see my problem. I've patched the problem by using a pointer to SomeClass however this would mean having an individual function call for every class type is there no way to store a function callback to a non-static class member without doing the below strategy? and instead doing a strategy like the commented out code?
//Main.cpp
#include <iostream> //system requires this.
#include "SomeClass.h"
void DoSomething1(void)
{
std::cout << "We Called Static DoSomething1\n";
}
void DoSomething2(void)
{
std::cout << "We Called Static DoSomething2\n";
}
int main()
{
void (*function_call2)(SomeClass*);
void (*function_call)() = DoSomething1; //This works No Problems!
function_call(); //Will Call the DoSomething1(void);
function_call = DoSomething2; //This works No Problems!
function_call(); //Will Call the DoSomething2(void);
SomeClass *some = new SomeClass(); //Create a SomeClass pointer;
function_call = SomeClass::DoSomething3; //Static SomeClass::DoSomething3();
function_call(); //Will Call the SomeClass::DoSomething3(void);
//function_call = some->DoSomething4; //Non-Static SomeClass::DoSomething4 gives an error.
//function_call(); //Not used because of error above.
function_call2 = SomeClass::DoSomething5; //Store the SomeClass::DoSomething(SomeClass* some);
function_call2(some); //Call out SomeClass::DoSomething5 which calls on SomeClass::DoSomething4's non static member.
system("pause");
return 0;
}
//SomeClass.hpp
#pragma once
#include <iostream>
class SomeClass
{
public:
SomeClass();
~SomeClass();
public:
static void DoSomething3(void);
void DoSomething4(void);
static void DoSomething5(SomeClass* some);
};
//SomeClass.cpp
#include "SomeClass.h"
SomeClass::SomeClass(void)
{
}
SomeClass::~SomeClass(void)
{
}
void SomeClass::DoSomething3(void)
{
std::cout << "We Called Static DoSomething3\n";
}
void SomeClass::DoSomething4(void)
{
std::cout << "We Called Non-Static DoSomething4\n";
}
void SomeClass::DoSomething5(SomeClass *some)
{
some->DoSomething4();
}
Secondary Fix for what I'll do not an exact answer I wanted but it meets my needs for now along with allowing additional features which would have become overly complicate had this not existed.
//Component.hpp
#pragma once
#include <iostream>
#include <windows.h>
#include <d3dx9.h>
#include <d3d9.h>
#include "Constants.hpp"
#include "ScreenState.hpp"
#include "ComponentType.hpp"
using namespace std;
class Component
{
static void EMPTY(void) { }
static void EMPTY(int i) { }
public:
Component(void)
{
callback = EMPTY;
callback2 = EMPTY;
callback_id = -1;
}
Component* SetFunction(void (*callback)())
{
this->callback = callback;
return this;
}
Component* SetFunction(void (*callback2)(int), int id)
{
this->callback_id = id;
this->callback2 = callback2;
return this;
}
void execute(void)
{
callback();
callback2(callback_id);
}
}
The syntax for pointers-to-member-functions is as follows:
struct Foo
{
void bar(int, int);
void zip(int, int);
};
Foo x;
void (Foo::*p)(int, int) = &Foo::bar; // pointer
(x.*p)(1, 2); // invocation
p = &Foo::zip;
(x.*p)(3, 4); // invocation
Mind the additional parentheses in the function invocation, which is needed to get the correct operator precedence. The member-dereference operator is .* (and there's also ->* from an instance pointer).