PDA

View Full Version : more of a C++ question



jajdoo
29th July 2010, 13:36
i have a class derived from QPlainTextEdit.
i added a member of type QList<[my struct]> to it. since that, the program fails to exit properly ( exit with code -1073741819 after 10-15 seconds of hold ) in debug mode.

any idea why?

tbscope
29th July 2010, 13:54
Post the code of your class please.

It's an access violation. Maybe you're trying to access an item in the list that doesn't exist (like in going beyond the item count of the list)

jajdoo
29th July 2010, 18:56
the thing is, it only happens in debug runs when i quit the program; release quits fine- i just cant find any logic to that.
the class is quite big, that was the reason i didn't post it in the first place. the structs involvement is somewhat minimal.

its somewhat disorganized since its still work in progress Frankenstein test subject..
i tried to cut the code down to only where the new list is relevant, which is still not small

the list i was refering to is "QList<folder> folders;"
it holds QChars for code folding (kinda)

#ifndef CODEEDITOR_H
#define CODEEDITOR_H

#include<QPlainTextEdit>
#include<QObject>
#include<QTextBlockUserData>
#include<QtGui>

class Highlighter;
class LineNumberArea;

struct folder
{
QChar open;
QChar close;
};

//--------------------------------------
class CodeEditor : public QPlainTextEdit
{
Q_OBJECT
public:
CodeEditor(QWidget* parent = 0);

void lineNumberAreaPaintEvent(QPaintEvent* event);
int lineNumberAreaWidth();

QCompleter* completer() const {return mCompleter;}
Highlighter* highlighter() const {return mHighligher;}

private:
bool event(QEvent *e);
void resizeEvent(QResizeEvent *e);
void focusInEvent(QFocusEvent *e);
void focusOutEvent(QFocusEvent *e);
void keyPressEvent(QKeyEvent *e);
void bracingEvent();
void homePressedEvent();
void tabPressedEvent(bool shiftPressed);

int findTwinBehind( folder req );
int findTwinAhead( folder req );
QString documentCommentClean(int start, int end);
QString indent();
void popCompleter();
void informCompleter();

private slots:
void updateLineNumberAreaWidth(int newBlockCount);
void makeExtraSelections();
void updateLineNumberArea(const QRect &, int);
void insertCompletion(const QString& completion);

private:
QWidget* lineNumberArea;
Highlighter* mHighligher;
QCompleter* mCompleter;
QList<folder> folders;
};
//--------------------------------------

#endif // CODEEDITOR_H




#include "codeEditor.h"
#include"highlighter.h"

CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent)
{
QStringList completionList;
completionList << "for" << "while" << "do" << "if" << "else";

lineNumberArea = new LineNumberArea(this);
mHighligher = new Highlighter(this->document());

mCompleter = new QCompleter(this);
mCompleter->setWidget(this);
mCompleter->setCompletionMode(QCompleter::PopupCompletion);
mCompleter->setModel(new QStringListModel(completionList,mCompleter));

connect(this, SIGNAL(blockCountChanged(int)),
this, SLOT(updateLineNumberAreaWidth(int)));

connect(this, SIGNAL(updateRequest(const QRect &, int)),
this, SLOT(updateLineNumberArea(const QRect &, int)));

connect(this, SIGNAL(cursorPositionChanged()),
this, SLOT(makeExtraSelections()));

connect(mCompleter, SIGNAL(activated(QString)),
this, SLOT(insertCompletion(QString)));

setStyleSheet("QPlainTextEdit { selection-background-color: darkgray }");
updateLineNumberAreaWidth(0);

folder fold;
fold.open = '{';
fold.close = '}';
folders.append(fold);

fold.open = '(';
fold.close = ')';
folders.append(fold);

fold.open = '[';
fold.close = ']';
folders.append(fold);
}

// ::::::: GENERAL METHODS :::::::
//---------------------------------------------------------------------------

void CodeEditor::makeExtraSelections()
{
QList<QTextEdit::ExtraSelection> extraSelections;

QTextEdit::ExtraSelection* selection;

// make current line glow yellow ( not related to the syntax highlighter )
//-----------------------------------------------------------
selection = new QTextEdit::ExtraSelection;
selection->format.setBackground(QColor(Qt::yellow).lighter(16 0));
selection->format.setProperty(QTextFormat::FullWidthSelection , true);
selection->cursor = textCursor();
selection->cursor.clearSelection();
extraSelections.append(*selection);
//-----------------------------------------------------------

// highlight parenthesis under cursor and its twin (behind or ahead)
//-----------------------------------------------------------
foreach( folder cur_fold, folders )
{
if( document()->characterAt(textCursor().position()-1) ==cur_fold.close)
{
selection = new QTextEdit::ExtraSelection() ;
selection->cursor = textCursor();
selection->cursor.movePosition(QTextCursor::PreviousCharacter , QTextCursor::KeepAnchor, 1);
selection->format.setForeground(QColor(Qt::red));
extraSelections.append(*selection);

selection = new QTextEdit::ExtraSelection() ;
selection->cursor = textCursor();
selection->cursor.setPosition(findTwinBehind(cur_fold)+1);
selection->cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1);
selection->format.setForeground(QColor(Qt::red));
extraSelections.append(*selection);
}
if( document()->characterAt(textCursor().position()-1) ==cur_fold.open)
{
selection = new QTextEdit::ExtraSelection() ;
selection->cursor = textCursor();
selection->cursor.movePosition(QTextCursor::PreviousCharacter , QTextCursor::KeepAnchor, 1);
selection->format.setForeground(QColor(Qt::red));
extraSelections.append(*selection);

selection = new QTextEdit::ExtraSelection() ;
selection->format.setForeground(QColor(Qt::red));
selection->cursor = textCursor();
selection->cursor.setPosition(findTwinAhead(cur_fold)-1);
selection->cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1);
extraSelections.append(*selection);
}
}
//-----------------------------------------------------------

setExtraSelections(extraSelections);
}
QString CodeEditor::documentCommentClean(int start, int end)
{
.........
//replace comment character with '@'
..........
}



// methods for finding matching pairs of expressions (parenthesis)
int CodeEditor::findTwinBehind( folder req )
{
QString cleaned = documentCommentClean(0, textCursor().position());

int i = cleaned.size()-2;
int braceBalance = -1;

while( i>0 && braceBalance<0 )
{
if(cleaned.at(i)==req.close) braceBalance-=1;
if(cleaned.at(i)==req.open) braceBalance+=1;
i--;
}
return i;
}

int CodeEditor::findTwinAhead( folder req )
{
QString cleaned = documentCommentClean(textCursor().position(), document()->characterCount());

int i = 0;
int braceBalance = 1;

while( i<cleaned.size() && braceBalance>0 )
{
if(cleaned.at(i)==req.close) braceBalance-=1;
if(cleaned.at(i)==req.open) braceBalance+=1;
i++;
}
return i+textCursor().position();
}


void CodeEditor::focusInEvent(QFocusEvent *e)
{
setReadOnly(false);
makeExtraSelections();
QPlainTextEdit::focusInEvent(e);
}


void CodeEditor::focusOutEvent(QFocusEvent *e)
{
setReadOnly(true);
QList<QTextEdit::ExtraSelection> extraSelections;
setExtraSelections(extraSelections);
QPlainTextEdit::focusOutEvent(e);
}

jajdoo
30th July 2010, 15:55
lets talk more basic - even when it is not referenced anywhere in the code, its very existence seems to disallow proper quitting exclusively in debug. what could be causing this?
i know i sound vague, but there isn't really much to it; if its there it crashes at exit in debug, if not it doesn't..

squidge
30th July 2010, 18:32
Post a small compilable example that causes the problem.

jajdoo
30th July 2010, 18:55
switched from MinGW to MSVC compilation; seems to have resolved the issue..

Chuk
17th August 2010, 20:40
I have seen something like this before, very hard to find. I think what helped was using .value(var) instead of .at(var), it's null pointer safe.