In Visual Studio 2015, the code shown below crashes at the exit of foo(), with this error message: HEAP[NameOfExecutable.exe]: Invalid address specified to RtlValidateHeap( 00520000, 005332D4 )
Notes:
When I remove the "virtual" keyword from B::bob(), the program works perfectly fine.
The program runs correctly from a command-line (outside of Visual Studio), when compiled with "g++ -std=c++11".
Using std::move() within push_back() didn't change the output.
#include <vector>
#include <memory>
#include <iostream>
class A
{
int a;
};
class B : public A
{
int b;
virtual void bob() { };
};
void foo()
{
std::vector<std::unique_ptr<A>> test;
test.push_back(std::unique_ptr<B>(new B));
}
int main()
{
foo();
std::cout << "Reached the end\n";
std::cin.get();
}
What am I doing wrong? Thanks for any help!
If you debug the code, you'll notice that the exception arises at the exit point of foo() - when the destructor for test is called.
Both std::vector and std::unique_ptr manage their memory of course, so somewhere at this point B object that you just allocated will be destroyed.
The problem here is that you store it by an A pointer, so the A class destructor will be called.
To fix that, just introduce public virtual destructor to 'A':
class A
{
int a;
public:
virtual ~A() {}
};
Related
I am trying to experiment bind in C++. Basically I have two class - Invokee. The invokee class registers a test handler that needs to be invoked upon some callbacks. The method here is -
void RegisterTestHandler(int id, TestFunction handler, std::string summary, std::string details);
Similarly, I have another method that actually invokes what has been registered -
void callHandler(int id);
Another class Test which has a function that needs to be invoked on callHandler.
unsigned int globalReset(int val);
In the main function, I am doing the nullptr for the second parameter in the bind. However, it still works and I don't get any crashes. Is it something working because of the compiler optimisation or undefined behaviour or it is something to do with bind concept.
Here is the entire experimental code.
// main.cpp
#include <iostream>
#include "test.h"
#include "invokee.h"
#include <memory>
#include <functional>
// beautify using clang-format in Vscode.
int main(int argc, char **argv)
{
auto *invokeTest = new Invokee();
Test *test = new Test();
std::string summary = "global reset summary";
std::string details = "global reset details";
//Basically there are two object from different class - InvokeTest --> does the registration of the handler.
// Now the InvokeTest has to call the member function of class object - Test.
// ?? How it can do - it can do using bind - basically, the this pointer of Test class is available to invokeTest
// therefore invokeTest can simply invoke the member function of test object.
// until the test point is valid, it can use it to invoke the method of it ?? --> Is it really correct?
delete(test); //experiment deleted the test pointer.
test= nullptr; // explicity set to nullptr
// still it works?? how come ??
invokeTest->RegisterTestHandler(1, std::bind(&Test::globalReset, test, std::placeholders::_1), summary, details);
invokeTest->callHandler(1);
return 0;
}
Here is the invokee.cpp -
#include "invokee.h"
void Invokee::RegisterTestHandler(int id, TestFunction handler, std::string summary, std::string details)
{
this->handlers[id] = handler;
this->summary[id] = summary;
this->details[id] = details;
}
void Invokee::callHandler(int id)
{
auto handler = handlers.find(id);
if (handler != handlers.end())
{
std::cout << "Found the handler --" << std::endl;
handler->second(1);
}
}
Here is the test.cpp
#include <iostream>
#include "test.h"
unsigned int Test::globalReset(int val)
{
std::cout << "global Reset invoked" << std::endl;
return 0;
}
I was reading the following post:
What changes introduced in C++14 can potentially break a program written in C++11?
and also the isocpp page:
https://isocpp.org/files/papers/p0636r0.html
So I became curious, according to the Standard: What changes introduced in C++11 can potentially break a program written in C++98?
Big one that stands out -- throwing exceptions from destructors.
In C++98 you can have programs that do this and work fine if you are careful.
In C++11 you will often have to explicitly declare the dtor noexcept(false).
Nice blog post here, on Andrzej's C++ blog.
In short, the following program used to run successfully in C++03 (under some definition of “success”):
struct S
{
~S() { throw runtime_error(""); } // bad, but acceptable
};
int main()
{
try { S s; }
catch (...) {
cerr << "exception occurred";
}
cout << "success";
}
In C++11, the same program will trigger the call to std::terminate.
Here is another case related to destructors are noexcept(true) in C++11:
// A simple program that demonstrates how C++11 and pthread_cancel don't play
// nicely together.
//
// If you build without C++11 support (g++ threadkill.cpp -lpthread), the
// application will work as expected. After 5 seconds, main() will cancel the
// thread it created and the program will successfully exit.
//
// If you build with C++11 support(g++ -std=c++11 threadkill.cpp -lpthread),
// the program will crash because the abi::__forced_unwind exception will
// escape the destructor, which is implicitly marked as noexcept(true) in
// C++11. If you mark the destructor as noexcept(false), the program does
// not crash.
#include <iostream>
#include <unistd.h>
#include <string.h>
class sleepyDestructorObject
{
public:
~sleepyDestructorObject() //noexcept(false)
{
std::cout << "sleepy destructor invoked" << std::endl;
while(true)
{
std::cout << "." << std::flush;
sleep(1);
}
}
};
void* threadFunc( void* lpParam )
{
sleepyDestructorObject sleepy;
return NULL;
}
int main(int argc, char** argv)
{
pthread_t tThreadID;
pthread_create(&tThreadID, NULL, threadFunc, NULL);
sleep(5);
pthread_cancel(tThreadID);
pthread_join(tThreadID, NULL);
return 0;
}
Original reference:
https://gcc.gnu.org/ml/gcc-help/2015-08/msg00036.html
Assume that I wanted to debug the following simple program. And that I want to define a breakpoint in the function bar().
#include <iostream>
void bar() {
std::cout << "Hello" << std::endl;
}
void foo() {
bar();
}
int main(int argc, char** args) {
bar();
foo();
return 0;
}
As a function might be called a lot of times in a real world example, I only wanted the debugger to stop if bar() was called inside foo(). So that the debugger will stop only once in the given example.
It should look like CALLER_FUNCTION=foo(), where foo() should be found somewhere in the stack backtrace.
Is it possible in MSVC2010 to define a conditional breakpoint that has this specific behavior?
I have this code that attempts perfect forwarding of template parameters pack into std::function via intermediate class:
#include <functional>
#include <vector>
#include <algorithm>
#include <iterator>
#include <memory>
#include <iostream>
template <typename ...Arguments>
class CSignal
{
public:
typedef std::function<void (Arguments...)> SignalFunction;
public:
void connect(const SignalFunction& target)
{
m_connections.emplace_back(std::make_shared<SignalFunction>(target));
}
template <typename ...ActualArguments>
void invoke(ActualArguments&&... args) const
{
for (auto& connection: m_connections)
if (connection)
(*connection)(std::forward<ActualArguments>(args)...);
}
private:
std::vector<std::shared_ptr<SignalFunction>> m_connections;
};
struct A
{
void f() {std::cout << __FUNCTION__ << "\n";}
};
void test(std::shared_ptr<A> ptr)
{
if (ptr)
ptr->f();
}
int main()
{
CSignal<std::shared_ptr<A>> signal;
signal.connect(test);
signal.connect(test);
signal.invoke(std::make_shared<A>());
return 0;
}
Problem: test is called twice, and the second time it's called its parameter is empty pointer. Why?
If I remove std::forward the issue disappears, but that's not what I want.
Yes; std::forward does the same thing as std::move when ActualArguments is not a reference type.
In terms of expiration, forward needs to be treated the same as move. Generally you do not forward or move inside a loop.
If you want to move the parameter on the last loop iteration, you'll have to break it out of the loop. That probably means not using the range-for syntax. However, you might ask whether this is a worthwhile optimization, and consider saving it for later when more performance data are available.
In MSVC 2008, I have the following code:
class Foo {
// Be a little smarter about deriving the vertex type, to save the user some typing.
template<typename Vertex> inline void drawVertices(
Elements vCount, RenPrim primitiveType, PixMaterial *mtl, Vertex const *vertices)
{
this->drawVertices(vCount, primitiveType, mtl, vertices, Vertex::VertexType);
}
virtual void drawVertices(
Elements vCount,
RenPrim primitiveType,
PixMaterial *mtl,
void const *vertices,
uint vertexType) = 0;
};
I use it something like:
struct RenFlexibleVertexPc
{
enum { VertexType = RenVbufVertexComponentsPc };
float x;
float y;
float z;
GraVideoRgba8 c; // Video format, not external!
};
PixMaterial *material;
struct Pc : RenFlexibleVertexPc
{
void set(Triple t, uint cl) { x = (float)t.x_; y = (float)t.y_; z = (float)t.z_; c = cl; }
} vpc[4];
...
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
This works fine in MSVC 2008 SP1. However, GCC (3.4 and 4.1,2) throws a "no matching function for call to function" error, apparently not seeing the template when there is a non-template function with more arguments.
Is GCC broken, or is my code broken, and if so, why?
There is no problem with overloading or inheritance:
#include <iostream>
#include <memory>
namespace {
struct A {
virtual void f()
{
std::cout<<"inside A's f()\n";
}
template <typename T> void f(T t)
{
std::cout<<T::i<<'\t';
this->f();
}
};
struct B : A {
void f()
{
std::cout<<"hello\t";
A::f();
}
};
struct C {
static const unsigned int i = 5;
};
struct D {
enum { i = 6 };
};
}
int main()
{
std::auto_ptr<A> b(new B());
b->f(C());
b->f(D());
}
Works correctly. On the other hand, the smallest example I can find that exhibits your problem does not have inheritance or overloading:
#include <iostream>
namespace {
struct A {
template<class C> void print(C c)
{
c.print();
}
};
}
int main()
{
struct B {
void print()
{
std::cout << "whee!\n";
}
};
A a;
B b;
a.print(b);
}
Note that if struct B is defined in a namespace (whether it's an unnamed namespace, or a completely different namespace, or the global namespace) instead of inside main() that this compiles without error.
I don't know enough of the standard to say if this is a bug, but it appears to be one. I've gone ahead and reported it to the GCC bug database.
And here's your answer from the GCC developers (from the link above): "Local classes cannot be template arguments."
So the code is broken. Not that it's a bad idea. In fact, C++0x removes this restriction.
I noticed the line
Note that the code works in GCC if I explicitly cast vpc to (RenFlexibleVertexPc *)
And since RenFlexibleVertexPc is not a local class this makes sense. However Pc is a local class/struct, so it is not allowed.
#OP: Specifying the template parameter is a valid approach.
renderer->drawVertices<RenFlexibleVertexPc>(4, RenPrimTriangleFan, material, vpc);
With Pete's additions, you code also compiles on Apple's GCC 4.0.1, so I suspect there's something your posted code is missing that's causing the problem.
#Max: GCC's treatment of your source is standard. Struct B is local to main(), so B (and thus main()::B::print()) is not visible outside main(). As you're probably aware, moving the definition of B outside of main() and it will compile.
The definition of VertexType is already in the code (an enum). Elements is an unsigned long. Note that the code works in GCC if I explicitly cast vpc to (RenFlexibleVertexPc *)
If it's an enum why pass an object of type array 4 of struct? What is RenFlexibleVertexPc? The last argument to drawVertices should either be a constant pointer to a Vertex object or a const* to an object of a class derived from Vertex.
Foo *renderer;
renderer->drawVertices(4, RenPrimTriangleFan, material, vpc);
You are calling a function on an uninitialized pointer. I hope this is not the real code. \