对于某些人来说,这可能是一个完全明显的错误,但我似乎无法找出为什么会发生这种分段错误。
我确实了解在访问我的程序不应访问的地址时会发生分段错误。
首先,我有一个名为“UiObject”的基类:
class UiObject {
private:
public:
UiObject();
virtual void render(char * imageBuffer) = 0;
};
然后,我从 UiObject 类派生多个其他类:例如 ProgressBar 类:
class ProgressBar : public UiObject {
private:
int x,y; // Position der ProgressBar auf dem Bildschirm (oben links) (Pixeln)
int width,height; // Breite und Höhe in Pixeln
public:
int maxProgress; // Maximal zu erreichner Fortschritt
long progress; // Fortschritt aktuell
ProgressBar(); // Constructor
void render(char * framebuffer); // Rendermethode
};
现在,这些对象由 UiManager 管理和呈现。函数 renderDisplay() 是使用 std::thread 创建的线程:
void UiManager::renderDisplays() {
printf("[RENDER] Render thread has been started\n[RENDER] (%x)\n", this);
while(!this->shouldStop) {
// Removed code that manages the timing of this function (running approximately 60FPS)
// Rendering:
for(Display d: displayArray) {
char * framebuffer = d.getFrameBuffer();
printf("Framebuffer: %x\n", framebuffer);
printf("uiArray: %x\n", uiArray);
printf("&uiArray: %x\n", &uiArray);
for(UiObject* pObject : uiArray) {
printf("[RENDER] (%x) Rendering Object...", pObject);
pObject->render(framebuffer);
}
d.renderDisplay();
}
}
}
如您所见,对于每个添加的显示,我都在检索帧缓冲区。我正在打开 /dev/fbX 文件,以便可以直接在屏幕上绘图。这一切都很好。d.getFramebuffer() 返回一个 char * 指针,以便我可以操作像素,然后将其传递给任何 UiObject 的 render(char * framebuffer) 函数。
但是,这个函数调用正在创建一个段错误,我不明白为什么。有时它会工作并一直运行直到线程应该停止,有时它会在第一次渲染函数调用后立即崩溃。
我使用以下方法将 UiObjects 添加到 UiManager:
ProgressBar pBar;
pBar.maxProgress = 60*15;
pBar.progress = 1;
uiArray.push_back(&pBar);
UiManager 有这个作为它的类定义:
class UiManager {
private:
char ttyfd; // TTY File Descriptor.
std::thread uiManagerThread;
std::chrono::system_clock::time_point timeA;
std::chrono::system_clock::time_point timeB;
std::chrono::duration<double, std::milli> work_time;
public:
std::vector<Display> displayArray;
std::vector<UiObject*> uiArray;
bool shouldStop;
bool displayFPS;
UiManager();
void stop();
void renderDisplays();
void addDisplay(Display d);
void startThread();
void stopThread();
};
现在我想知道为什么会这样。
根据 cppreference https://en.cppreference.com/w/cpp/language/abstract_class及其关于抽象类的文档,我不允许有 =0; 在我的 UiObject 类中。如果我删除它,我将在链接过程中收到编译器警告,并显示消息“未定义对 UiObject 的 vtable 的引用”。
我做错了什么?
我怀疑 std::vector 和 for 循环在 UiManager 中不太有效。
我在 debian 上使用 g++ 作为我的编译器。
我的控制台输出:
[RENDER] Render thread has been started
[RENDER] (6ea609f0)
Framebuffer: e09f0010
uiArray: e09eed20
&uiArray: 6ea60a30
./run.sh: Zeile 21: 25018 Speicherzugriffsfehler ./a.out
它甚至不跳入 ProgressBar 渲染例程。我还注释掉了渲染函数的内容,因此我只能怀疑特定的函数调用。