I have a C++ code as follow:
tryIt.h file
class tryIt : public someOtherClass
{
public:
bool insertI ();
private:
CommandI* m_pInsertI;
bool createInsertI();
}
tryIt.cpp file
tryIt ::tryIt () : m_pInsertI(NULL)
{
createInsertI();
}
tryIt ::~tryIt ()
{
if(m_pInsertI!=NULL)
{
delete m_pInsertI;
m_pInsertI=NULL
}
}
bool createInsertI()
{
m_pInsertI = returnFromSomeOtherFunction();
return true;
}
bool insertI()
{
// Over here if I use m_pInsertI anyhow my code fails with seg fault
// even checking if(m_pInsertI==NULL) make the code throw seg fault
}
So the issue is touching m_pInsertI anywhere make my code throw Seg. fault (Signal 11). Even debugged the code with GDB but didn't got any useful info.
Compiler is GCC
Please help.
Sounds like the instance of this class does not exist or damaged.
That is why you can't access any of its members and even if(m_pInsertI==NULL) check raises the exception.
in tryIt.cpp shouldn't
bool createInsertI()
be
bool tryIt::createInsertI()
same with insertI()
I see the following two possibilities:
returnFromSomeOtherFunction() already returns a corrupted pointer
You are copying your instance using the compiler generated methods (see example below)
Example (Rule of three violation)
tryIt instance1; // allocates instance2.m_pInsertI
{
tryIt instance2;
instance1 = instance 2; // performs a shallow copy
} // here, instance2.m_pInsertI is deleted
instance1.insertI(); // access violation
Recommendation:
Whether or not this is cause your problem: Do not implement manual memory management. Simply use a std::unique_ptr<CommandI> for m_pInsertI instead, so you do not need to implement the destructor or copy constructors/operators.
Related
I have a shared library for library interposition with an unordered_map.
The unordered_map is filled and consulted through the execution of an application (when intercepting specifics calls).
If I try to find an element in the constructor of the library, it generates a segmentation fault.
Here is the code for the constructor causing the segmentation fault:
void __attribute__((constructor)) init(void) {
void * address = __builtin_extract_return_addr(__builtin_return_address(0));
printf ("Size: %i\n", stats._regions.size()); // works fine
auto regionIt = stats._regions.find(address);
printf ("Never reached\n");
}
Stats is declared in the header, like this:
class Stats {
public
std::unordered_map<void *, RegionInfo> _regions;
}
As said, if I do the find when intercepting specific calls (not in the constructor), it works fine.
Here is the code for the constructor causing the segmentation fault:
You didn't show how the stats global itself is declared, and without that your code is useless (see also MCVE).
But this is almost certainly an instance of static initialization order fiasco.
How can I test if is SIOF? And fix it if that's the case
The usual way to fix SIOF: instead of declaring stats as a global, make it a function-static and return a reference to it, which guarantees that it will be initialized before you access it:
Stats& get_stats()
{
static Stats stats;
return stats;
}
Your constructor will then look like this:
void __attribute__((constructor)) init(void) {
Stats& stats = get_stats();
// rest as before
}
If this fixes the crash, you'll know that it was an instance of SIOF.
I have a class which is loaded from an external file, so ideally I would want its constructor to load from a given path if the load fails, I will want to throw an error if the file is not found/not readable (Throwing errors from constructors is not a horrible idea, see ISO's FAQ).
There is a problem with this though, I want to handle errors myself in some controlled manner, and I want to do that immediately, so I need to put a try-catch statement around the constructor for this object ... and if I do that, the object is not declared outside the try statement, i.e.:
//in my_class.hpp
class my_class
{
...
public:
my_class(string path);//Throws file not found, or other error error
...
};
//anywhere my_class is needed
try
{
my_class my_object(string);
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
//Problem... now my_object doesn't exist anymore
I have tried a number of ways of getting around it, but I don't really like any of them:
Firstly, I could use a pointer to my_class instead of the class itself:
my_class* my_pointer;
try
{
my_class my_pointer = new my_class(string);
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
The problem is that the instance of this object doesn't always end up in the same object which created it, so deleting all pointers correctly would be easy to do wrong, and besides, I personally think it is ugly to have some objects be pointers to objects, and have most others be "regular objects".
Secondly, I could use a vector with only one element in much the same way:
std::vector<my_class> single_vector;
try
{
single_vector.push_back(my_class(string));
single_vector.shrink_to_fit();
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
I don't like the idea of having a lot of single-element vectors though.
Thirdly, I can create an empty faux constructor and use another loading function, i.e.
//in my_class.hpp
class my_class
{
...
public:
my_class() {}// Faux constructor which does nothing
void load(string path);//All the code in the constructor has been moved here
...
};
//anywhere my_class is needed
my_class my_object
try
{
my_object.load(path);
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
This works, but largely defeats the purpose of having a constructor, so I don't really like this either.
So my question is, which of these methods for constructing an object, which may throw errors in the constructor, is the best (or least bad)? and are there better ways of doing this?
Edit: Why don't you just use the object within the try-statement
Because the object may need to be created as the program is first started, and stopped much later. In the most extreme case (which I do actually need in this case also) that would essentially be:
int main()
{
try
{
//... things which might fail
//A few hundred lines of code
}
catch(/*whaveter*/)
{
}
}
I think this makes my code hard to read since the catch statement will be very far from where things actually went wrong.
One possibility is to wrap the construction and error handling in a function, returning the constructed object. Example :
#include <string>
class my_class {
public:
my_class(std::string path);
};
my_class make_my_object(std::string path)
{
try {
return {std::move(path)};
}
catch(...) {
// Handle however you want
}
}
int main()
{
auto my_object = make_my_object("this path doesn't exist");
}
But beware that the example is incomplete because it isn't clear what you intend to do when construction fails. The catch block has to either return something, throw or terminate.
If you could return a different instance, one with a "bad" or "default" state, you could have just initialized your instance to that state in my_class(std::string path) when it was determined the path is invalid. So in that case, the try/catch block is not needed.
If you rethrow the exception, then there is no point in catching it in the first place. In that case, the try/catch block is also not needed, unless you want to do a bit of extra work, like logging.
If you want to terminate, you can just let the exception go uncaught. Again, in that case, the try/catch block is not needed.
The real solution here is probably to not use a try/catch block at all, unless there is actually error handling you can do that shouldn't be implemented as part of my_class which isn't made apparent in the question (maybe a fallback path?).
and if I do that, the object is not declared outside the try statement
I have tried a number of ways of getting around it
That doesn't need to be a problem. There's not necessarily need to get around it. Simply use the object within the try statement.
If you really cannot have the try block around the entire lifetime, then this is a use case for std::optional:
std::optional<my_class> maybe_my_object;
try {
maybe_my_object.emplace(string);
} catch(...) {}
The problem is that the instance of this object doesn't always end up in the same object which created it, so deleting all pointers correctly would be easy to do wrong,
A pointer returned by new is correct to delete. In the error case, simply set the pointer to null and there would be no problem. That said, use a smart pointer instead for dynamic allocation, if you were to use this approach.
single_vector.push_back(my_class(string));
single_vector.shrink_to_fit();
Don't push and shrink when you know the number of objects that are going to be in the vector. Use reserve instead if you were to use this approach.
The object creation can fail because a resource is unavailable. It's not the creation which fails; it is a prerequisite which is not fulfilled.
Consequently, separate these two concerns: First obtain all resources and then, if that succeeded, create the object with these resources and use it. The object creation as such in this design cannot fail, the constructor is nothrow; it is trivial boilerplate code (copy data etc.). If, on the other hand, resource acquisition failed, object creation and object use are both skipped: Your problem with existing but unusable objects is gone.
Responding to your edit about try/catch comprising the entire program: Exceptions as error indicators are better suited for things which are done in many places at various times in a program because they guarantee error handling (by default through an abort) while separating it from the normal control flow. This is impossible to do with classic return value examination, which leaves us with a choice between unreadable or unreliable programs.
But if you have long-lived objects which are created only rarely (in your example: only at startup) you don't need exceptions. As you said, constructor exceptions guarantee that only properly initialized objects can be used. But if such an object is only created at startup this danger is low. You check for success one way or another and exit the program which cannot perform its purpose if the initial resource acquisition failed. This way the error is handled where it occurred. Even in less extreme cases (e.g. when an object is created at the beginning of a large function other than main) this may be the simpler solution.
In code, my suggestion looks like this:
struct T2;
struct myEx { myEx(const char *); };
void exit(int);
T1 *acquireResource1(); // e.g. read file
T2 *acquireResource2(); // e.g. connect to db
void log(const char *what);
class ObjT
{
public:
struct RsrcT
{
T1 *mT1;
T2 *mT2;
operator bool() { return mT1 && mT2; }
};
ObjT(const RsrcT& res) noexcept
{
// initialize from file data etc.
}
// more member functions using data from file and db
};
int main()
{
ObjT::RsrcT rsrc = { acquireResource1(), acquireResource2() };
if(!rsrc)
{
log("bummer");
exit(1);
}
///////////////////////////////////////////////////
// all resources are available. "Real" code starts here.
///////////////////////////////////////////////////
ObjT obj(rsrc);
// 1000 lines of code using obj
}
I'm having trouble adding a unit test for a class that I have. One of the functions uses a boost pointer (dynamic pool) and there's always a segmentation fault that occurs whenever I compile the test as seen from the backtrace. If run normally, it compiles properly but when using Google Mock it fails.
The Mock::AllowLeak also does not seem to work for me. Unfortunately, I cannot share the code in public so if anybody has experienced testing functions that uses boost pointers with Google Mock feel free to share some tips.
Thank you
Function to be tested:
RetObj* Foo::FooFunction(uint32_t param1)
{
spRetObj_t ptr = pool_storage->Get<RetObj>(); //error occurs when I use this
...
return ptr;
}
spRetObj_t initialize:
typedef stdex::IPool<RetObj>::iptr spRetObj_t;
Pool storage:
#include "stdex/dynamic_pool.hpp"
...
class PoolStorage
{
...
template<typename T>
typename stdex::IPool<T>::iptr Get(void (T::*on_free)(void) = 0);
...
}
Code in boost where the exception was thrown:
T * operator->() const
{
BOOST_ASSERT( px != 0 );
return px;
}
hi i'm trying to send a QList as a parameter to another class but for some reason i got a read access violation...
CompareTimeChannel.h
class CompareTimeChannel : public IDataChannel
public:
// #brief The method used to receive the list
void setData(const QList< QSharedPointer<core::ITrackSection> > & sections);
// #brief The list
QList< QSharedPointer<core::ITrackSection> > _sections;
};
CompareTimeChannel.cpp
// #brief Empty constructor
CompareTimeChannel::CompareTimeChannel()
{
}
void CompareTimeChannel::setData(const QList< QSharedPointer<core::ITrackSection> > & sections)
{
//_sections = *new QList< QSharedPointer<core::ITrackSection> > ();
_sections.clear();
_sections.append(sections);
}
Running this code will throw Exception at 0x31cc78d, code: 0xc0000005: read access violation at: 0x4, flags=0x0 on _sections.clear();
I tried to initialize the list before (the commented line _sections = *new QList<...>) but the exception is thrown the same.
An answer would be very appreciated...
EDIT
Ok it's fixed!
First, like #AndreasT said, i had to initialize the default QList constructor.
Then, according to #10WaRRioR01 's answer, the issue comes from CompareTimeChannel which wasn't initialized the first time the method was called. Fixed using :
CompareTimeChannel* chan = static_cast<CompareTimeChannel*>(channel);
Q_ASSERT(chan);
if (chan) {
chan->setData(sections);
}
else {
qDebug() << "Dynamic cast failure";
}
Thank you all, guys!
//_sections = *new QList< QSharedPointer<core::ITrackSection> > ();
You shouldn't ever do something like this. This creates a new instance of QList on the heap and it will never be deleted, so you have a memory leak
You should have done
_sections = QList< QSharedPointer<core::ITrackSection> > ();
instead, and it would be legal. But the most simple way is to use a copy assignment like this
_sections = sections
The problem you got is most likely related to the data you have in _sections. Maybe you are calling your methods on a null CompareTimeChannel object
You should initialize sections in the constructor.
The commented line is just horribly wrong.
new constructs the List on the heap, then you dereference that with *new and the assignment implicitly calls the copy constructor of the new list on the Heap and copies that into the instance. The thing on the heap is still aruond though, so you just created a memory leak.
// #brief Empty constructor
CompareTimeChannel::CompareTimeChannel()
:_sections() // initialization default constructor.
{
}
Edit regarding the comment:
The QList.clear() method calls the destructors of every element of the list. At least one of your shared pointers seems not to be initialized correctly. If you need more info, please paste the code that puts stuff into _sections.
Edit Regarding the exception:
As I said the problem is most likely with the shared pointers not being set to anything interesting. When the SP gets destroyed it calls the destructor of its content, which must exist, otherwise it throws a read access violation, which would explain the symptoms.
This what you showed should work. Your problem is in some other place.
This kind of problems might be caused by many different mistakes, like: bad static_cast or bad c-style cast, break in binary compatibility when you are using dynamic libraries, write outside of table, problems with compiler cache (this happens is quite often so cure for that is below).
First what I would try to do:
make clean
qmake
make
This fixes such problem quite often. if i doesn't help you have to find other problems in your code.
I have written a few C++ classes which employ a variety C++ libraries. I made a Windows Form project, and set it up to use my classes successfully. However, I recently made another C++ class and now I consistently get:
A first chance exception of type 'System.AccessViolationException' occurred in TEST_OCU.exe
which leads to:
An unhandled exception of type 'System.TypeInitializationException' occurred in Unknown Module.
Additional information: The type initializer for '<Module>' threw an exception.
The program hasn't even started running yet, and the new, problem-causing C++ class hasn't even been constructed yet. If I comment out the new call, and only have a pointer to this new C++ class, everything compiles just fine. BUT, if somewhere I do something like:
if(new_class_ptr != NULL)
new_class_ptr->SomeFunction() //It doesn't matter what function this is
This will throw those violations again
Some facts:
Compiling and linking is fine, this seems to be a run-time problem.
My solution employs unmanaged C++ libraries and classes (that I have written), and one managed C++ Form.
So far I haven't had any problems, I've used a few C++ libraries successfully for a while. This is caused by a new C++ class I recently wrote.
The C++ class which causes these violations uses std::ifstream to read in a file. If I comment out the std::ifstream input_file(filename); my Forms project runs successfully.
If I use the C++ class in a simple Win32 project, it compiles and runs just fine with the std::ifstream.
I have a strong feeling it is related to this question
Could anyone offer any advice? Thank you
EDIT: I'm providing some parts of my form code I have. RTSPConnection works just fine, the offending class is RTPStream
public ref class Form1 : public System::Windows::Forms::Form
{
public:
// ... Lots of generated code here ...
//Calls I've written
private: static RTSPConnection * rtsp_connection_ = NULL; //This class works
private: static RTPStream * rtp_connection_ = NULL; //This class does not
bool streaming_;
System::Threading::Thread^ streaming_thread_;
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
if(rtsp_connection_ == NULL)
{
rtsp_connection_ = new RTSPConnection("rtsp://192.168.40.131:8554/smpte");
streaming_ = false;
}
//if(rtp_connection_ == NULL)
// rtp_connection_ = new RTPStream("test");
}
private: System::Void Form1_FormClosing(System::Object^ sender, System::Windows::Forms::FormClosingEventArgs^ e) {
if(rtsp_connection_ != NULL)
rtsp_connection_->StopStreaming();
}
private: System::Void button1_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) {
if(!streaming_)
{
//Start Streaming
streaming_thread_ = gcnew Thread(gcnew ThreadStart(&Form1::WorkerThreadFunc));
streaming_thread_->Start();
this->button1->Text = L"Stop Streaming";
streaming_ = true;
}
else
{
//Stop Streaming
if(rtsp_connection_ != NULL)
rtsp_connection_->StopStreaming();
//THIS CALL RIGHT HERE WILL THROW AN ACCESS VIOLATION
if(rtp_connection_ != NULL)
rtp_connection_->StopStreaming();
this->button1->Text = L"Start Streaming";
streaming_ = false;
}
}
};
These two statements appear to contradict each other:
The program hasn't even started running yet, and the new,
problem-causing C++ class hasn't even been constructed yet.
If I comment out the new call, and only have a pointer to this new C++
class, everything compiles just fine.
Q: Could you please post the code where you're calling "new"? Or are you calling "new" - perhaps you just meant "if I comment out my new class"?
Q: Could you please set a breakpoint in your constructor, look at the stack trace, and see who's invoking it? And when?
========== ADDENDUM ==========
I strongly disagree with this statement:
It all hinges on this line: std::ifstream input_file(filename);
where filename is a std::string.
I strong AGREE with this statement:
You get almost the same error in C# if you have static class members
that depend on each other and they aren't initialised in the order you
expect. In C++, if you had a static singleton and another static
member that referred to it
Calling "ifstream" isn't the problem per se. Rather, somehow invoking the class that invokes ifstream before the program has initialized is the problem.
Q: Are you calling "new" on this class? If so, where. Please cut/paste that code.
Per MSDN, you should be able to set "mixed mode debugging". I have lots of different copies of MSVS :) ... but MSVS 2010/C++ doesn't happen to be one of them. Please look at this documentation:
http://msdn.microsoft.com/en-us/library/fz5w87ad.aspx
http://msdn.microsoft.com/en-us/library/cktt23yw