使用拖动 wxFileDropTarget 时出现分段错误的原因
我尝试进行简单的拖放(将文件拖到文本区域)。我通过两种方式实现了拖放。让我们将它们标记为 V1
和 V2
。
在这两个版本中,拖放功能都可以正常工作,但在 V1
中,当我尝试退出应用程序时,会出现分段错误。
问题:
也许有人可以启发我为什么使用 V1
会出现分段错误,而使用 V2
则不会出现分段错误? (我使用V2
没有真正的问题,只是想知道发生分段错误的原因)
版本的简短描述:
- V1 - 有一个名为
Notepad
的类。它继承于wxFrame
和wxFileDropTarget
,并封装wxTextCtrl
并实现OnDropFiles(
- V2 - class
Notepad< /code> 仅从
wxFrame
继承并封装wxTextCtrl
,Drang'n'drop 由名为的单独类完成。DRPTARGET
,继承于wxFileDropTarget
,并实现了OnDropFiles(
代码说明
(这里删掉了很多代码,不是我希望我没有删掉太多)
V1
:
#include <wx/wx.h>
#include <wx/dir.h>
#include <wx/dnd.h>
class Notepad : public wxFrame , public wxFileDropTarget {
public:
Notepad();
private:
wxTextCtrl* text_area;
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames);
};
bool Notepad::OnDropFiles (wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxArrayString &filenames){
return this->text_area->LoadFile(filenames[0]);
}
Notepad::Notepad() : wxFrame(NULL, wxID_ANY, wxT("V1"), wxDefaultPosition, wxSize(650,500)) {
wxBoxSizer *sizerh = new wxBoxSizer(wxHORIZONTAL);
this->text_area = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER | wxTE_MULTILINE);
sizerh->Add(this->text_area,1,wxEXPAND,0);
this->SetSizer(sizerh);
this->text_area->SetDropTarget(this);
}
V2
:
#include <wx/wx.h>
#include <wx/dir.h>
#include <wx/dnd.h>
class DRPTARGET : public wxFileDropTarget{
private:
wxTextCtrl* text_area;
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames)
{
return this->text_area->LoadFile(filenames[0]);
};
public:
DRPTARGET(wxTextCtrl* text_area)
{
this->text_area = text_area;
};
};
class Notepad : public wxFrame , public wxFileDropTarget {
public:
Notepad(); // our default constructor
private:
wxTextCtrl* text_area;
};
Notepad::Notepad() : wxFrame(NULL, wxID_ANY, wxT("V2"), wxDefaultPosition, wxSize(650,500)) {
wxBoxSizer *sizerh = new wxBoxSizer(wxHORIZONTAL);
this->text_area = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER | wxTE_MULTILINE);
sizerh->Add(this->text_area,1,wxEXPAND,0);
this->SetSizer(sizerh);
DRPTARGET* drop_target = new DRPTARGET(this->text_area);
this->text_area->SetDropTarget(drop_target);
}
I try to do simple drag'n'drop (drag file to text area). I implemented drag'n'drop in 2 ways. Lets mark them V1
and V2
.
In both versions drag'n'drop works OK, but in V1
I get segmentation fault when I try to exit the application.
Question:
Maybe somebody could enlighten me why with V1
I get segmentation faul, while no segmentation fault with V2
?
(I have no real problem using V2
, just want to know the reason why segmenation fault occurs)
Short descriptions of the versions:
- V1 - There is one class named
Notepad
. It inherits fromwxFrame
andwxFileDropTarget
, and encapsulateswxTextCtrl
and implementsOnDropFiles(
- V2 - class
Notepad
ingerits only fromwxFrame
and encapsulateswxTextCtrl
. Drang'n'drop is done by separate class calledDRPTARGET
, which inherits fromwxFileDropTarget
and implementsOnDropFiles(
Code for ilustration
(I cut out a lot of code here, which was not relevant. I hope I did not cut out too much)
V1
:
#include <wx/wx.h>
#include <wx/dir.h>
#include <wx/dnd.h>
class Notepad : public wxFrame , public wxFileDropTarget {
public:
Notepad();
private:
wxTextCtrl* text_area;
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames);
};
bool Notepad::OnDropFiles (wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxArrayString &filenames){
return this->text_area->LoadFile(filenames[0]);
}
Notepad::Notepad() : wxFrame(NULL, wxID_ANY, wxT("V1"), wxDefaultPosition, wxSize(650,500)) {
wxBoxSizer *sizerh = new wxBoxSizer(wxHORIZONTAL);
this->text_area = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER | wxTE_MULTILINE);
sizerh->Add(this->text_area,1,wxEXPAND,0);
this->SetSizer(sizerh);
this->text_area->SetDropTarget(this);
}
V2
:
#include <wx/wx.h>
#include <wx/dir.h>
#include <wx/dnd.h>
class DRPTARGET : public wxFileDropTarget{
private:
wxTextCtrl* text_area;
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames)
{
return this->text_area->LoadFile(filenames[0]);
};
public:
DRPTARGET(wxTextCtrl* text_area)
{
this->text_area = text_area;
};
};
class Notepad : public wxFrame , public wxFileDropTarget {
public:
Notepad(); // our default constructor
private:
wxTextCtrl* text_area;
};
Notepad::Notepad() : wxFrame(NULL, wxID_ANY, wxT("V2"), wxDefaultPosition, wxSize(650,500)) {
wxBoxSizer *sizerh = new wxBoxSizer(wxHORIZONTAL);
this->text_area = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER | wxTE_MULTILINE);
sizerh->Add(this->text_area,1,wxEXPAND,0);
this->SetSizer(sizerh);
DRPTARGET* drop_target = new DRPTARGET(this->text_area);
this->text_area->SetDropTarget(drop_target);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当注册了放置目标时,wxWidgets 会很好地在退出主循环后删除指针。问题与文件放置目标对象的范围有关。
V1
在这个版本中,“this”指的是框架。请记住,窗口指针也是由 wxWidgets 管理的;帧指针在文件放置目标之前被删除。当wxWidgets尝试删除放置目标指针时,它将尝试删除已经被删除的指针。
V2
这种情况下,指针分配在堆中;但从未删除。在这种情况下,当 wxWidgets 尝试删除它时,它可以安全地执行此操作。
When a drop target is registered, wxWidgets will be nice and delete the pointer after the it exits the main loop. The problem has to do with the scope of the file drop target object.
V1
In this version, "this" refers to the frame. Remember that the window pointers are also managed by wxWidgets; the frame pointer is deleted before the file drop target. When wxWidgets tries to delete the drop target pointer it will attempt to delete a pointer that has already been deleted.
V2
In this case, the pointer is allocated in the heap; but never deleted. In this case, when wxWidgets attempts to delete it it can do so safely.