PDA

View Full Version : Problem pointing to a QStringList



ljuhrich
10th November 2012, 12:22
I wanted to make my application logging, so I added a "QStringList l" to my Mainwindow Class.
Because the Program has some sub-classes that also should be logging, I added Pointers to the mainwindow's QStringList into them.
The program executes the Pledge-Algorithm for a robot to leave a room full of blocks, so I created the Classes "CPledge", "CRob" and "CMap".

The problem: I get a SIGSEGV error when I reference the log-lists of CRob/CMap to the Mainwindow's logList.
CODE:
Mainwindow Class:

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

// !The Log Object!
QStringList l;

void saveLog(QString file);

private:
Ui::MainWindow *ui;


QString i(int i);
QString dt();

private slots:
void on_btStartThread_clicked();
// etc.
};


#endif // MAINWINDOW_H


The CPledge Class (Gets the CRob out of a CMap):

class CPledge : public QObject
{
Q_OBJECT
public:
explicit CPledge(QObject *parent = 0);

CMap *map;
CRob *rob;
void setBot(int x, int y);
// Log list reference
QStringList *l;

private:
void followLeftWallTilTurnIsZero();

public slots:
void solve(QString filePath);

signals:
void finished();
};

The CMap Class (The Labyrinth):

class CMap : public QObject
{
Q_OBJECT
public:
explicit CMap(QObject *parent = 0);
// Log list reference
QStringList *l;

typedef QList<bool> StonesLine;

void loadFromFile(QString FilePath);

bool free(int x, int y);
bool left(int x, int y, int turn);
bool front(int x, int y, int turn);
QPoint movedPos(int x, int y, int turn);

int cleanTurning(int turn);

QPoint *defaultRobPos;

private:
// A 2D bool-list: 1->stone; 0-> No stone
QList <StonesLine> stones;
// The list of points where the rob is free
QPoint freePoints[2];

void insertBlock(int x1, int y1, int x2, int y2);
void initBlocks(int width, int height);

StonesLine horizontalStonesBorder(int width);
StonesLine verticalStonesBorder(int width);
};

The CRob Class (The Robot):

class CRob : public QObject
{
Q_OBJECT
public:
explicit CRob(QObject *parent = 0);
// Log list reference
QStringList *l;

bool free();

bool left();
bool front();

void turnR();
void turnL();

void move();

void setPosition(int newx, int newy);

int turning();

private:
int x, y;
CMap *map;

int fturning;
};


The Error comes here at Mainwindow.cpp:

// etc.
void MainWindow::on_btStartThread_clicked()
{
CPledge *pledge = new CPledge();
pledge->l = &l;
// #########FATAL SIGSEGV ERROR################
pledge->rob->l = &l;
pledge->map->l = &l;


pledge->solve(ui->edMapPath->text());
}
// etc.

amleto
10th November 2012, 14:58
Get your debugger out and then tell me the values of:

pledge->rob
pledge->map

ljuhrich
10th November 2012, 15:22
Stopping at a breakpoint after "pledge->l = &l;", I get following content:


&l <0 Elements> @0x22fe60 QStringList
pledge->l <0 Elements> @0x22fe60 QStringList
pledge->map 3131961357 @0xbaadf00d CMap
pledge->rob 3131961357 @0xbaadf00d CRob


pledge->rob->l <unavailable synchronous data>
pledge->map->l <unavailable synchronous data>

what does "<unavailable synchronous data>" mean?

Added after 7 minutes:

Oh, I forgot initializing the map and rob inside CPledge;
Thank you ;)

amleto
10th November 2012, 15:51
;)


...10 chars..

ljuhrich
10th November 2012, 17:45
...10 chars..
what do you mean with this?

but now there's another problem:

In CRob functions, I cannot access the QStringList *l.
Code as above, and an error comes here:

bool CRob::free()
{
bool free = map->free(x, y);
if (free) {
l << "FREE";
}
return free;
}

The error at l << etc. is
"crob.cpp:17: error: invalid operands of types 'QStringList*' and 'const char [5]' to binary 'operator<<'"

Zlatomir
10th November 2012, 17:58
That l is a pointer to a QStringList isn't it? If so try de-referencing it: *l << "FREE"; and make sure that function isn't called before the pointer l is initialized.

Also some of Qt's classes have implicit sharing (http://doc.qt.digia.com/qt/implicit-sharing.html), read about that and then decide if you really need to complicate your life with heap allocation of the container (or value and implicit-share or reference or const reference doesn't do the trick). Holding an container directly in a class doesn't increase the size of that class with the size of all elements allocated in the container (the elements are most likely heap allocated by the container), so you can use QStringList member instead of a pointer (like you did with the other l - also you should use better names for your variables ;) )

amleto
10th November 2012, 18:09
what do you mean with this?


There is a 10 char minimum limit for posts so I wasn't allowed to reply with

;) as it's only two chars.

ljuhrich
10th November 2012, 18:35
That l is a pointer to a QStringList isn't it? If so try de-referencing it: *l << "FREE"; and make sure that function isn't called before the pointer l is initialized.


Sorry, I forgot writing that it also doesn't work with dereferencing - when I say '*l << "FREE"', the compiler also says "no match for operator<<".
but it anyway seems strange that QtCreator doesn't recognize l being QStringList*, because it doesn't change "l." into "l->"...

Added after 4 minutes:

That works with the private CMap *map, but when I add a private QStringList *testlog, it doesn't work either...

Zlatomir
10th November 2012, 18:38
Make sure that you have #include <QStringList> in your .cpp file and not only a forward declaration of QStringList class.

amleto
10th November 2012, 19:05
Sorry, I forgot writing that it also doesn't work with dereferencing - when I say '*l << "FREE"', the compiler also says "no match for operator<<".
but it anyway seems strange that QtCreator doesn't recognize l being QStringList*, because it doesn't change "l." into "l->"...

Added after 4 minutes:

That works with the private CMap *map, but when I add a private QStringList *testlog, it doesn't work either...

show your code. This should work fine. Proof:

http://www.comeaucomputing.com/tryitout/



#include <string>

class MockQStrList
{
public:
MockQStrList();
~MockQStrList();

MockQStrList& operator<<(std::string const & )
{
return *this;
}
};

int main()
{

MockQStrList* l = new MockQStrList;

*l << "";

}

ljuhrich
10th November 2012, 19:58
#include <QStringList> solved it...

I did not add ti because QtCreator recognized QStringList, so I thought it would not be necessary...

thanks for taking you time...