I am trying to fix a memory leak found is this code by val-grind. I did not write it, but I reduced the original code down to using ofstream and not filebuf and ostream.
The problem is I can't figure out how to properly delete the ofstream pointer which is shared and called from a virtual getter method in other code. I think this code violates the rule of 3 but trying different assignment and copy constructors did not work.
Below is an example of the basic code I am trying to fix, when it goes to delete the ofstream pointer is seg faults. Before the segfault I was getting a double delete error.
If anyone can please help, I seem to be stuck here, thanks.
class myLogger
{
public:
myLogger(std::string testName);
void createFileLog();
...
protected:
std::ofstream* my_LogStream;
};
void MyLogger::createFileLog()
{
if(Created == false)
{
m_pLogStream = new std::ofstream(logFileName.c_str(), std::ofstream::out);
Created = true;
}
}
myLogger::~myLogger()
{
if(m_pLogStream)
{
delete m_pLogStream;
m_pLogStream = NULL;
}
}
I found in a higher call it was using a copy and calling the destructor twice.
Related
A have a problem trying to stop my QProcess in it's parent destructor. Here is my code:
AbstractProcess::~AbstractProcess()
{
if((m_process->state() == QProcess::Running)
|| (m_process->state() == QProcess::Starting))
{
m_process->terminate();
m_process->waitForFinished();
}
}
m_process is a pointer to QProcess. In AbstractProcess's constructor I have this code:
m_process = new QProcess(this);
So, when AbstractProcess is deleted I get to it's destructor and I have a segmentation fault at :
m_process->waitForFinished();
Can anybody tell me what my mistake is?
UPD:
As was said below in the comments the problem was not in the code that I provided. Very sorry for that. So I will try to explain what the problem was. Maybe it will help somebody. AbstractProcess as you might guess by the name is an abstract class. So it has some pure virtual functions. On of them is:
virtual void onProcessFinished(int exitCode, QProcess::ExitStatus
exitStatus) = 0;
The full body of my constructor is:
m_process = new QProcess(this);
connect(m_process,static_cast<void(QProcess::*)(int,QProcess::ExitStatus)>(&QProcess::finished),
this, &AbstractProcess::onProcessFinished);
And now it's obvious that on calling waitForFinished the process emits signal finished and the pure virtual function is called. That leads to undefined behaviour. To fix this I call disconnect before stopping my process. The destructor now looks like this:
AbstractProcess::~AbstractProcess()
{
disconnect(m_process,static_cast<void(QProcess::*)(int,QProcess::ExitStatus)>(&QProcess::finished),
this, &AbstractProcess::onProcessFinished)
if((m_process->state() == QProcess::Running)
|| (m_process->state() == QProcess::Starting))
{
m_process->terminate();
m_process->waitForFinished();
}
}
Thanx everybody for your help.
When you call m_process->terminate(); first, there is no guarantee that the process will exit .. yet there is no guarantee that the process will continue to exist because of calling (WM_CLOSE on windows / SIGTERM on Linux) so calling for m_process->waitForFinished(); on a process that might have already been terminated might cause segmentation fault.
the right and safe approach is to do the right things in order:
m_process->waitForFinished();
m_process->terminate();
We are in the process of converting C# code to C++, but we need to do so in phases. I am at a point now where I need to instantiate several native objects from within managed code. These native objects I cannot change, and their declaration looks like this:
public class NativeA();
public class NativeB(std::shared_ptr<NativeA> obj);
Both NativeA and NativeB need to be instantiated from managed code as:
void main() {
ManagedA ObjectA = gcnew ManagedA();
ManagedB ObjectB = gcnew ManagedB(ObjectA);
}
The problem comes in with getting the shared_ptr of NativeA in the constructor of NativeB. Niether NativeA nor NativeB will be manipulated in managed code, they just need to be instantiated. Ideally, something like this:
public ref class ManagedA {
public:
ManagedA() { _object = new NativeA(); }
~ManagedA() { delete _object; }
NativeA * Get() { return _object; }
private:
NativeA *_object;
};
public ref class ManagedB {
public:
ManagedB(ManagedA^ objectA ) {
_object = new NativeB(std::make_shared<NativeA>(*objectA->Get());
}
~ManagedB() { delete _object; }
private:
NativeB *_object;
};
But, this is not allowed in c++/cli because native types are declared as private. Defining #pragma make_public(NativeA) does not solve this either.
My intent is not to work with the native objects in managed code, they just need to be instantiated, so I really don't care about trying to marshal the native pointers and deal with .NET GC if I don't have to, and I don't want to perform a copy. I just want to wrap the classes in order to pass them around.
Is there a clean and simple way to do this?
It appears that the answer was not due to a syntax or usage problem. The two managed objects were in different DLLs and could not be passed across them via .NET. Once the code was compiled in the same project, the issue was resolved.
Although the error message indicated the problem was an accessibility issue in VS 2015, and because it reported it during the link phase, I suspect the cause was because the linker would not have known about the implementation of the NativeA in NativeB without declaring an extern. Being wrapped in CLR, it surfaced as a different issue.
is it okay to do something like this, the code snippet is of course not complete, just to show what I mean:
void draw(IplImage* image){
cvLine(image,cvPoint(20,20),cvPoint(100,100),cvScalar(0,0,255),1);}
int main(){
cvNamedWindow("preview",CV_WINDOW_AUTOSIZE);
IplImage* image;
image=cvCreateImage(cvSize(480,360),8,3);
while(true){
draw(image);
cvShowImage("preview",image);
int ops=cvWaitKey(10)
if ops!=-1 break;}
cvReleaseImage(&image);cvDestroyWindow("preview");return 0;
}
or will it cause problems if I don't return the IplImage like this:
IplImage* draw(IplImage* image){
cvLine(image,cvPoint(20,20),cvPoint(100,100),cvScalar(0,0,255),1);return image;}
well, the reason why I'm asking is that sometimes it works if I don't return the IplImage. However it may also happen that I'll receive some sort of NULL pointer error message in other cases. If for example I release the image in the function and then create it anew right after that, still being in that function, a crash may happen.
You don't need to return anything, but you definitely need to check for failures!
The problem is that you are not coding safely. You are never checking for failures when calling OpenCV functions, which may result in draw() receiving a NULL pointer as parameter, and that might cause a crash or some other weird behavior along the way.
The first thing you should do is start coding defensively:
IplImage* image = cvCreateImage(cvSize(480,360),8,3);
if (!image)
{
// print error and quit
}
and it wouldn't hurt to add a safety check inside your function:
void draw(IplImage* image)
{
if (!image)
{
// print error
return;
}
cvLine(image,cvPoint(20,20),cvPoint(100,100),cvScalar(0,0,255),1);
}
Perhaps there is a fancy term for this. Lets say I have this code:
void a(){
b();
}
void b(){
c();
}
void c(){
a();
// do something
if (FLAG_COMPLETE){
return;
}
}
The problem is it will go a->b->c->a->b->c until it FLAG_COMPLETE goes up. After it will track back through ALL those calls in back order. Is there a way to avoid the return to caller function from the callee? I know in assembly this would be quite easy to do.
I am using C++ CLI. I want to avoid overflowing the stack by calling functions in a loop.
If I read between the lines, it sounds like you want the contents of a(), then b(), then c(), to run forever, until FLAG_COMPLETE is set? If that's the case, then why not do that explicitly?
void RunUntilComplete()
{
while(!FLAG_COMPLETE)
{
ContentsOfA();
ContentsOfB();
ContentsOfC();
}
}
Sorry for my english, but I have the next problem. I am writing a window manager using Qt 4.7 and Xlib. I have class Manager that inherits QApplication and reimplemented method X11EventFilter in it. In X11EventFilter method I catch necessary events from XServer. When I receive MapRequest event, I catch appearing of new window and reparent it to my own widget. And when I create that widget and call QWidget::show() or QWidget::winId() methods, program crashes. What is the problem?
Here is a method where widget is creating. I wonder, when this function calls few times on start of program, everything is OK.
void Manager::createClientWindow(Qt::HANDLE pWinID)
{
QMWindowWidget *lWindowWidget = new QMWindowWidget(pWinID);
/*some code*/
lWindowWidget->show();//crash is here
Qt::HANDLE widgetId = lWindowWidget->winId();//and here
/*some code*/
}
Here is a x11EventFilter method where createClientWindow function is called
bool Manager::x11EventFilter(XEvent *pEvent)
{
switch(pEvent.type)
{
/*some code*/
case MapRequest:
{
Qt::HANDLE lWindow = pEvent->xmaprequest.window;
QMWindowWidget* lWidget = findWidget(lWindow);
if (!lWidget)
{
lWidget = dynamic_cast<QMWindowWidget*>(QWidget::find(lWindow));
}
if (lWidget)
{
XMapWindow(QX11Info::display(), lWindow);
lWidget->show();
XRaiseWindow(QX11Info::display(), lWidget->winId());
return true;
}
else
{
createClientWindow(lWindow);//here is where function is called
return true;
}
}
break;
/*some code*/
} //switch
return false;
}
The problem most likely resides in the code represented by /*some code*/. Since it is not known what's there, it's very difficult to pinpoint the exact cause of the problem. If you cannot show all the code, you will have to track the problem down yourself.
You will need to build in debug mode and link with the debug version of Qt. Then when the crash happens, look at the exact line of Qt source and analyse the broken data structures with a debugger and try to figure out why they are broken. Maybe set a watchpoint on a problematic variable and find out what code writes an invalid value there.
In order to program in low level languages such as C and C++ one has to learn how to do this stuff.
Problem is resolved! I paste this two strings before QApplication::exec()
XClearWindow(QX11Info::display(), QX11Info::appRootWindow());
XSync(QX11Info::display(), false);