• 7640阅读
  • 13回复

[提问]很奇怪,棘手的问题!貌似和编译器底层有关的 [复制链接]

上一主题 下一主题
 

只看楼主 倒序阅读 楼主  发表于: 2011-10-09

我跑一个人家写好的例子,跑起来没问题,但是我自己改了下,运行错误如下:



后来我设置断点调试我改动过的程序时,第一个断点时:






continue,下一个断点:






再下一个断点,它显示





我试过利用断点测试那个没改动过的程序(就是正确那个),显示如下:






简单来说,就是多了这行:0 QObject::connect qobject.cpp 2510 0x6a20f9e8 ,而且报错说内存不能read就是这个地址。是不是也就是说是
    connect(loginDialog->registerButton,SIGNAL(clicked()),this,SLOT(showRegisterDialog()));
    connect(loginDialog->loginButton,SIGNAL(clicked()),this,SLOT(tryToConnectToServer()));
这两行有问题。并且是connect问题,把这两行注释掉的话,就能跑,但是功能实现不了了!是不是改了以后就是给QObject::connect qobject.cpp分配内存,并且内存溢出了?

只看该作者 1楼 发表于: 2011-10-09
怎么会报connect错误呢!!奇怪了!
离线xinqingfly

只看该作者 2楼 发表于: 2011-10-09
你确定在login的类构造函数中new了loginDialog->registerButton和loginDialog->loginButton?
菜鸟也是鸟
离线dbzhang800

只看该作者 3楼 发表于: 2011-10-09
引用第2楼xinqingfly于2011-10-09 13:40发表的  :
你确定在login的类构造函数中new了loginDialog->registerButton和loginDialog->loginButton?


恩,应该可以肯定是这种野指针造成的。不过动不动上升到编译器底层的高度可不好。(当然编译器bug也很多,但我们遇到并确认是bug的机会却非常少,一般都是自己犯傻造成的)
离线eadywen

只看该作者 4楼 发表于: 2011-10-09
registerButton 跟 loginButton 是public的吗 ?
离线dbzhang800

只看该作者 5楼 发表于: 2011-10-09
引用第4楼eadywen于2011-10-09 17:07发表的  :
registerButton 跟 loginButton 是public的吗 ?

都编译通过,开始调试了。不管是public,还是通过friend的方式,都和这个问题无关了。
离线mewjerry
只看该作者 6楼 发表于: 2011-10-09
代码贴到pastebin上,没代码没法看。

只看该作者 7楼 发表于: 2011-10-10
回 6楼(mewjerry) 的帖子
代码如下:widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QSqlTableModel>
#include <qstringlist>
#include <qstringlistmodel>
#include "login.h"
#include "datatype.h"
#include "clientsocket.h"
#include "registerdialog.h"
#include <QCloseEvent>


#define SERVERADDRESS "219.222.170.15"
#define SERVERPORT 3800
namespace Ui {
    class Widget;
}

class Widget : public QWidget//, public Ui::Widget
{
    Q_OBJECT
public:
    explicit Widget(QString n, QString p, QWidget *parent = 0);
    Widget(QWidget *parent = 0);

    ~Widget();
protected:
    void closeEvent(QCloseEvent *event);
    Ui::Widget *ui;

private:
    QString username;
    QString password;
    QString selfname;
    QSqlTableModel *model;
    ClientSocket client;
    login *loginDialog;
    RegisterDialog *registerDialog;
    QStringList nameList;
    QStringListModel nameModel;

    void makeConnections();
    void logining();
private slots:
    void showConnectedInLabel();
    void showDisconnectedInLabel();
    void sendMessage();
    void addNewComerToNameList(const QString &newName,const QHostAddress &address);
    void showMessageInTextEdit(const QString &hisName,const QString &currentDateTime,const QString &message);
    void removeLeaverNameFromNameList(const QString &name);
    void nameAndPasswordIsNotRight();
    void nameAndPasswordIsRight();
    void showRegisterDialog();
    void tryToConnectToServer();
    void registerSuccess();
    void registerFailed();
    void tryToRegister();
    void goBackToLoginDialog();
};
#endif // WIDGET_H


login.h:


#ifndef LOGIN_H
#define LOGIN_H

#include <QDialog>
#include "ui_login.h"
/*
namespace Ui {
    class login;
}*/
class login : public QDialog,public Ui::login
{
    Q_OBJECT
public:
    login(QWidget *parent = 0);
    QString GetName();
    QString GetPwd();
    ~login();
protected:
    void changeEvent(QEvent *e);


private:
    Ui::login *ui;

private slots:
  /*  void on_registerButton_clicked();
    void on_forgetButton_clicked();
    void on_saveButton_clicked();
    void on_autorloginBox_clicked();
    void on_setButton_clicked();
    void on_loginButton_clicked();*/
    void setloginButtonEnable(const QString &name);
private:
    QString username;
    QString password;
};

#endif // LOGIN_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <qdatastream>
#include <qbytearray>
#include <qmessagebox>
#include <qdatetime>
#include "login.h"
#include <qhostaddress>
#include <qsizepolicy>
//#include <stdio.h>

Widget::Widget(QString n, QString p, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
    {
    ui->setupUi(this);
    username = n;
    password = p;
    model = new QSqlTableModel(this);
    model->setTable("user");
    model->setFilter(tr("username = '%1'").arg(username));
    model->select();
    ui->label->setText(tr("%1,欢迎您!").arg(username));
    ui->selfnamelabel->setText(tr("%2").arg(selfname));
    setFixedSize(width(),height());
    setAttribute(Qt::WA_DeleteOnClose);

    makeConnections();
    logining();
    }


//============================================================================
//
//      进入loginDialog
//
//============================================================================
void Widget::logining()
{
    loginDialog=new login(this);
    loginDialog->show();
    connect(loginDialog->registerButton,SIGNAL(clicked()),this,SLOT(showRegisterDialog()));
    connect(loginDialog->loginButton,SIGNAL(clicked()),this,SLOT(tryToConnectToServer()));
}

void Widget::showConnectedInLabel()
{
    ui->stateLabel->setText(tr("connected"));
}

void Widget::showDisconnectedInLabel()
{
    ui->stateLabel->setText(tr("disconnected"));
}
//============================================================================
//
//      进入registerDialog
//
//============================================================================

void Widget::showRegisterDialog()
{
    loginDialog->hide();
    registerDialog=new RegisterDialog(this);
    registerDialog->show();
    connect(registerDialog->okButton,SIGNAL(clicked()),this,SLOT(tryToRegister()));
    connect(registerDialog->concelButton,SIGNAL(clicked()),this,SLOT(goBackToLoginDialog()));

}

//============================================================================
//
//      向服务器发注册信息
//
//============================================================================
void Widget::tryToRegister()
{
    if(client.state()==QAbstractSocket::UnconnectedState){
        client.connectToHost(QHostAddress(SERVERADDRESS),SERVERPORT);
        if(!client.waitForConnected(3000)){
            QMessageBox::warning(registerDialog,
                             tr("!!!"),
                             tr("failed to connect"));
        }
        client.isRegistering=true;
    }
    QString name=registerDialog->nameLineEdit->text();
    QString password=registerDialog->passwordLineEdit->text();
    QString passwordAgain=registerDialog->passwordAgainLineEdit->text();
    if(name.isEmpty()){
        QMessageBox::warning(registerDialog,
                             tr("!!!"),
                             tr("invalid name"));
    }
    else if(password!=passwordAgain){
        QMessageBox::warning(registerDialog,
                             tr("!!!"),
                             tr("password is not the same"));
    }else{
        QByteArray buffer; //QByteArray类提供了一个字节数组
        quint16 blockSize; //quint16 是QT软件下的一种自定义类型,他代表32位计算机中的整型,其功能好比C++/C中的int型
        QDataStream out(&buffer,QIODevice::WriteOnly);
        out<<(quint16)0<<(quint16)REGISTER<<name<<password;
        blockSize=(quint16)(sizeof(buffer)-sizeof(quint16)-sizeof(quint16));
        out.device()->seek(0);
        out<<blockSize;
        client.write(buffer);
    }
}

void Widget::goBackToLoginDialog()
{
    registerDialog->close();
    registerDialog->deleteLater();
    loginDialog->show();
    client.isRegistering=false;
}

void Widget::closeEvent(QCloseEvent *event)
{
    int standardButton=QMessageBox::warning(this,
                                           tr("quit?"),
                                           tr("do you want to leave?"),
                                           QMessageBox::Ok | QMessageBox::Cancel,
                                           QMessageBox::Cancel);
    if(standardButton==QMessageBox::Ok){
        client.close();
        event->accept();
    }else{
        event->ignore();
    }
}

void Widget::tryToConnectToServer()
{
    client.setName(loginDialog->numuberEdit->text());
    client.setPassword(loginDialog->keyEdit->text());

    nameList.clear();
    nameList.append(client.name());
    nameModel.setStringList(nameList);
    ui->nameListView->setModel(&nameModel);

    if(client.state()==QAbstractSocket::UnconnectedState){
        client.connectToHost(QHostAddress(SERVERADDRESS),SERVERPORT);
        if(!client.waitForConnected(3000)){
            QMessageBox::warning(registerDialog,
                             tr("!!!"),
                             tr("failed to connect"));
        }
    }else{
        client.tellOthersThatICame();
    }
}


void Widget::makeConnections()
{
    connect(ui->sendPushButton,SIGNAL(clicked()),
            this,SLOT(sendMessage()));
    connect(&client,SIGNAL(connected()),
            this,SLOT(showConnectedInLabel()));
    connect(&client,SIGNAL(disconnected()),
            this,SLOT(showDisconnectedInLabel()));
    connect(&client,SIGNAL(addNewComerToNameList(const QString &,const QHostAddress &)),
            this,SLOT(addNewComerToNameList(const QString &,const QHostAddress &)));
    connect(&client,SIGNAL(showMessageInTextEdit(const QString &,const QString &,const QString &)),
            this,SLOT(showMessageInTextEdit(const QString &,const QString &,const QString &)));
    connect(&client,SIGNAL(nameAndPasswordIsRight()),
            this,SLOT(nameAndPasswordIsRight()));
    connect(&client,SIGNAL(nameAndPasswordIsNotRight()),
            this,SLOT(nameAndPasswordIsNotRight()));
    connect(&client,SIGNAL(removeLeaverNameFromNameList(const QString &)),
            this,SLOT(removeLeaverNameFromNameList(const QString &)));
    connect(&client,SIGNAL(registerSuccess()),
            this,SLOT(registerSuccess()));
    connect(&client,SIGNAL(registerFailed()),
            this,SLOT(registerFailed()));
}

void Widget::registerSuccess()
{
    QMessageBox::information(registerDialog,
                         tr("!!!"),
                         tr("register success"));
    goBackToLoginDialog();
}

void Widget::registerFailed()
{
    QMessageBox::warning(registerDialog,
                         tr("!!!"),
                         tr("name already exist"));
}

void Widget::addNewComerToNameList(const QString &newName,const QHostAddress &address)
{
    int row=nameModel.rowCount();
    nameModel.insertRow(row);
    nameModel.setData(nameModel.index(row),newName,Qt::DisplayRole);
}

void Widget::showMessageInTextEdit(const QString &hisName,const QString &currentDateTime,const QString &message)
{
    ui->showTextEdit->append(QString("\n[%1] %2 %3\n%4")
                        .arg(currentDateTime)
                        .arg(hisName)
                        .arg(QString::fromLocal8Bit("说道:"))
                        .arg(message) );
}

void Widget::removeLeaverNameFromNameList(const QString &name)
{
    for(int i=0;i<nameModel.rowCount();i++){
        if(nameModel.data(nameModel.index(i),Qt::DisplayRole)==name){
            nameModel.removeRow(i);
        }
    }
}

void Widget::nameAndPasswordIsNotRight()
{
    loginDialog->informationLabel->setText(tr("incorrect password!"));
}

void Widget::nameAndPasswordIsRight()
{
    delete loginDialog;
    show();
}

void Widget::sendMessage()
{
    client.sendMessage(ui->inputTextEdit->toPlainText());
}


Widget::~Widget()
{

}





只看该作者 8楼 发表于: 2011-10-10
回 2楼(xinqingfly) 的帖子
那些控件在ui文件里。widget.h中,loginDialog是继承login。(login *loginDialog; 红色字体)。

只看该作者 9楼 发表于: 2011-10-10
那个能运行的代码(就是那个我没改动过的)如下:zzworldclient.h
#ifndef SMALLCHAT_H
#define SMALLCHAT_H

#include <QtGui/QWidget>
#include "ui_zzworldclient.h"
#include <qcloseevent>
#include <qstringlist>
#include <qstringlistmodel>
#include "login.h"
#include "datatype.h"
#include "clientsocket.h"
#include "registerdialog.h"

#define SERVERADDRESS "219.222.170.15"
#define SERVERPORT 3800

class ZzWorldClient : public QWidget,public Ui::ZzWorldClient
{
    Q_OBJECT

public:
    ZzWorldClient(QWidget *parent = 0);
    ~ZzWorldClient();
protected:
    void closeEvent(QCloseEvent *event);
private:
    ClientSocket client;
    Login *loginDialog;
    RegisterDialog *registerDialog;
    QStringList nameList;
    QStringListModel nameModel;

    void makeConnections();
    void logining();

private slots:
    void showConnectedInLabel();
    void showDisconnectedInLabel();
    void sendMessage();
    void addNewComerToNameList(const QString &newName,const QHostAddress &address);
    void showMessageInTextEdit(const QString &hisName,const QString &currentDateTime,const QString &message);
    void removeLeaverNameFromNameList(const QString &name);
    void nameAndPasswordIsNotRight();
    void nameAndPasswordIsRight();
    void showRegisterDialog();
    void tryToConnectToServer();
    void registerSuccess();
    void registerFailed();
    void tryToRegister();
    void goBackToLoginDialog();
};

#endif // SMALLCHAT_H


login.h

#ifndef LOGIN_H
#define LOGIN_H

#include <QDialog>
#include "ui_login.h"

class Login : public QDialog,public Ui::Login
{
    Q_OBJECT

public:
    Login(QWidget *parent);

private slots:
    void setEnterButtonEnable(const QString &name);
};

#endif // LOGIN_H


zzworldclient.cpp

#include "zzworldclient.h"
#include "ui_zzworldclient.h"

#include <qdatastream>
#include <qbytearray>
#include <qmessagebox>
#include <qdatetime>
#include "login.h"
#include <qhostaddress>
#include <qsizepolicy>
//#include <stdio.h>

ZzWorldClient::ZzWorldClient(QWidget *parent)
    : QWidget(parent)
{
    setupUi(this);
    setFixedSize(width(),height());
    setAttribute(Qt::WA_DeleteOnClose);

    makeConnections();
    logining();


}

//============================================================================
//
//      进入loginDialog
//
//============================================================================
void ZzWorldClient::logining()
{
    loginDialog=new Login(this);
    loginDialog->show();
    connect(loginDialog->registerButton,SIGNAL(clicked()),this,SLOT(showRegisterDialog()));
    connect(loginDialog->enterButton,SIGNAL(clicked()),this,SLOT(tryToConnectToServer()));
    connect(loginDialog->closeButton,SIGNAL(clicked()),qApp,SLOT(quit()));
}

void ZzWorldClient::showConnectedInLabel()
{
    stateLabel->setText(tr("connected"));
}

void ZzWorldClient::showDisconnectedInLabel()
{
    stateLabel->setText(tr("disconnected"));
}

//============================================================================
//
//      进入registerDialog
//
//============================================================================

void ZzWorldClient::showRegisterDialog()
{
    loginDialog->hide();
    registerDialog=new RegisterDialog(this);
    registerDialog->show();
    connect(registerDialog->okButton,SIGNAL(clicked()),this,SLOT(tryToRegister()));
    connect(registerDialog->concelButton,SIGNAL(clicked()),this,SLOT(goBackToLoginDialog()));
}

//============================================================================
//
//      向服务器发注册信息
//
//============================================================================
void ZzWorldClient::tryToRegister()
{
    if(client.state()==QAbstractSocket::UnconnectedState){
        client.connectToHost(QHostAddress(SERVERADDRESS),SERVERPORT);
        if(!client.waitForConnected(3000)){
            QMessageBox::warning(registerDialog,
                             tr("!!!"),
                             tr("failed to connect"));
        }
        client.isRegistering=true;
    }
    QString name=registerDialog->nameLineEdit->text();
    QString password=registerDialog->passwordLineEdit->text();
    QString passwordAgain=registerDialog->passwordAgainLineEdit->text();
    if(name.isEmpty()){
        QMessageBox::warning(registerDialog,
                             tr("!!!"),
                             tr("invalid name"));
    }
    else if(password!=passwordAgain){
        QMessageBox::warning(registerDialog,
                             tr("!!!"),
                             tr("password is not the same"));
    }else{
        QByteArray buffer; //QByteArray类提供了一个字节数组
        quint16 blockSize; //quint16 是QT软件下的一种自定义类型,他代表32位计算机中的整型,其功能好比C++/C中的int型
        QDataStream out(&buffer,QIODevice::WriteOnly);
        out<<(quint16)0<<(quint16)REGISTER<<name<<password;
        blockSize=(quint16)(sizeof(buffer)-sizeof(quint16)-sizeof(quint16));
        out.device()->seek(0);
        out<<blockSize;
        client.write(buffer);
    }
}

void ZzWorldClient::goBackToLoginDialog()
{
    registerDialog->close();
    registerDialog->deleteLater();
    loginDialog->show();
    client.isRegistering=false;
}

void ZzWorldClient::closeEvent(QCloseEvent *event)
{
    int standardButton=QMessageBox::warning(this,
                                           tr("quit?"),
                                           tr("do you want to leave?"),
                                           QMessageBox::Ok | QMessageBox::Cancel,
                                           QMessageBox::Cancel);
    if(standardButton==QMessageBox::Ok){
        client.close();
        event->accept();
    }else{
        event->ignore();
    }
}

void ZzWorldClient::tryToConnectToServer()
{
    client.setName(loginDialog->nameLineEdit->text());
    client.setPassword(loginDialog->passwordLineEdit->text());

    nameList.clear();
    nameList.append(client.name());
    nameModel.setStringList(nameList);
    nameListView->setModel(&nameModel);

    if(client.state()==QAbstractSocket::UnconnectedState){
        client.connectToHost(QHostAddress(SERVERADDRESS),SERVERPORT);
        if(!client.waitForConnected(3000)){
            QMessageBox::warning(registerDialog,
                             tr("!!!"),
                             tr("failed to connect"));
        }
    }else{
        client.tellOthersThatICame();
    }
}


void ZzWorldClient::makeConnections()
{
    connect(sendPushButton,SIGNAL(clicked()),
            this,SLOT(sendMessage()));
    connect(&client,SIGNAL(connected()),
            this,SLOT(showConnectedInLabel()));
    connect(&client,SIGNAL(disconnected()),
            this,SLOT(showDisconnectedInLabel()));
    connect(&client,SIGNAL(addNewComerToNameList(const QString &,const QHostAddress &)),
            this,SLOT(addNewComerToNameList(const QString &,const QHostAddress &)));
    connect(&client,SIGNAL(showMessageInTextEdit(const QString &,const QString &,const QString &)),
            this,SLOT(showMessageInTextEdit(const QString &,const QString &,const QString &)));
    connect(&client,SIGNAL(nameAndPasswordIsRight()),
            this,SLOT(nameAndPasswordIsRight()));
    connect(&client,SIGNAL(nameAndPasswordIsNotRight()),
            this,SLOT(nameAndPasswordIsNotRight()));
    connect(&client,SIGNAL(removeLeaverNameFromNameList(const QString &)),
            this,SLOT(removeLeaverNameFromNameList(const QString &)));
    connect(&client,SIGNAL(registerSuccess()),
            this,SLOT(registerSuccess()));
    connect(&client,SIGNAL(registerFailed()),
            this,SLOT(registerFailed()));
}

void ZzWorldClient::registerSuccess()
{
    QMessageBox::information(registerDialog,
                         tr("!!!"),
                         tr("register success"));
    goBackToLoginDialog();
}

void ZzWorldClient::registerFailed()
{
    QMessageBox::warning(registerDialog,
                         tr("!!!"),
                         tr("name already exist"));
}

void ZzWorldClient::addNewComerToNameList(const QString &newName,const QHostAddress &address)
{
    int row=nameModel.rowCount();
    nameModel.insertRow(row);
    nameModel.setData(nameModel.index(row),newName,Qt::DisplayRole);
}

void ZzWorldClient::showMessageInTextEdit(const QString &hisName,const QString &currentDateTime,const QString &message)
{
    showTextEdit->append(QString("\n[%1] %2 %3\n%4")
                        .arg(currentDateTime)
                        .arg(hisName)
                        .arg(QString::fromLocal8Bit("说道:"))
                        .arg(message) );
}

void ZzWorldClient::removeLeaverNameFromNameList(const QString &name)
{
    for(int i=0;i<nameModel.rowCount();i++){
        if(nameModel.data(nameModel.index(i),Qt::DisplayRole)==name){
            nameModel.removeRow(i);
        }
    }
}

void ZzWorldClient::nameAndPasswordIsNotRight()
{
    loginDialog->informationLabel->setText(tr("incorrect password!"));
}

void ZzWorldClient::nameAndPasswordIsRight()
{
    delete loginDialog;
    show();
}

void ZzWorldClient::sendMessage()
{
    client.sendMessage(inputTextEdit->toPlainText());
}

ZzWorldClient::~ZzWorldClient()
{

}
其实我只是吧zzworldclient.h和.cpp文件改成widget.h和.cpp文件,(ui以及控件相应改了过来了)。

只看该作者 10楼 发表于: 2011-10-10
回 3楼(dbzhang800) 的帖子
恩恩!昨天自己看半天,总感觉自己代码没错!现在想想很大可能是registerButton 跟 loginButton 问题!!谢谢大侠!

只看该作者 11楼 发表于: 2011-10-10
回 5楼(dbzhang800) 的帖子
是编译通过了的!第一次遇到这种问题!无从下手啊!registerButton 跟 loginButton 检查来检查去都没发现什么错误!
离线eadywen

只看该作者 12楼 发表于: 2011-10-10
方便打包你的工程吗
离线mewjerry
只看该作者 13楼 发表于: 2011-10-22
楼主,你loginDialog的定义在哪。
快速回复
限100 字节
 
上一个 下一个