2011-10-03 4 views
0

저는 Qt와 C++에 새로 도입되었지만 프로그래밍에 익숙하지 않았습니다. 내 프로그램에서 포인터를 사용하는 데 문제가 있습니다. 내 헤더 파일에서 나는 다음과 같은 전용 변수 포인터 할당을 가지고있다 :Qt에서 포인터 값을 수신하려 할 때 세그먼트 오류가 발생했습니다.

나는 다른 QString 변수에 currentFile 포인터의 값을 복사하여 시작하는 기능을 가지고있다 내 프로그램에서
private: 
    QString *currentFile; 

:

QString fileName = *currentFile; 

그러나 이것은 즉시 디버깅 할 때 세그먼테이션 오류를 발생시킵니다. 내가 뭘 잘못하고 있는지 전혀 모른다.

포인터의 vlue를 얻으려는 함수를 호출 할 때까지 프로그램이 잘 실행됩니다. 그러나 이것은 단지 즉시 나에게 세그먼트 오류를 ​​준

*currentFile = QString::null; 

포인터 값에 null 값을 지정하려면 : 나는 포인터가 비어 becuase 내 constructer에 다음 코드를 추가하는 시도 그래서 수 있습니다 생각 생성자가 호출되었습니다.

누군가가 도움을 줄 수 있기를 바랍니다.

감사

편집

더 많은 코드 :

notepad.h :

class Notepad : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    Notepad(); 

private slots: 
    void open(); 
    void save(); 
    void saveAs(); 
    void quit(); 

private: 
    QTextEdit *textEdit; 
    QString *currentFile; 
    QString *currentContents; 
}; 

오류를 생성하는 기능 메모장을 (무효()를 저장). cpp :

void Notepad::save(){ 
    QString fileName = *currentFile; 
    if(fileName != "") 
    { 
     QFile file(fileName); 
     if(!file.open(QIODevice::WriteOnly)) 
     { 
      QMessageBox::critical(this, tr("Error"), tr("Could not write to file")); 
      return; 
     } 
     else 
     { 
      QTextStream stream(&file); 
      QString editorContent = textEdit->toPlainText(); 
      currentContents = &editorContent; 
      stream << editorContent; 
      stream.flush(); 
      file.close(); 
     } 
    } 
    else 
     saveAs(); 
} 
+1

더 많은 코드를이 시도. 또한 포인터를 사용하지 마십시오. 포인터가 필요하지 않습니다. –

+0

더 많은 코드가 추가되었습니다 .. – Simon

+0

'* currentFile = QString :: null'이 생성자에서 초기화되지 않은 포인터를 역 참조합니다. 무엇이든, 이것은'currentFile = QString :: null'이어야합니다. – eran

답변

2

delete currentFile;를 넣어 . 포인터는 단지 메모리 주소를 저장하고 그 값이 0으로 초기화되거나 (심지어 더 나쁘고 완전히 정의되지 않은 주소를 포함하는 경우) 유효한 문자열 객체를 가리 키지 않으며 포인터가 가리키는 메모리를 사용하려고 시도합니다 문자열 개체는 정의되지 않은 동작을 발생시킵니다 (사용자의 경우 segfault).

따라서 문자열에 대한 메모리를 할당하고 (아마 주변 객체의 생성자)를 사용하여 문자열을 구성하는 첫번째 필요 : 나중에

currentFile = new QString; 

와 (주변 개체의 소멸자 예를 들어, 더 이상 필요하지 않을 때) :

delete currentFile; 

그러나 의견에서 말한 것처럼 나는 포인터 멤버가 필요하다는 것을 정말로 알고 있습니다. 왜 그냥 QString 개체를 회원으로 사용하지 않는가? 또는 포인터가 필요하면 오히려 스마트 포인터 (auto_ptr 또는 새로운 C++ 11 unique_ptr 또는 shared_ptr)를 사용하십시오.

QObject 파생 된 유형 (위젯 등)은 다른 이야기이며, 대신 포인터를 사용해야합니다 (Qt가 적절하게 사용되면 할당 해제 처리). 하지만 QString은 (보통 문자열과 비슷합니다) 다소 값이 비슷한 유형 (내장 유형과 유사)이며 대부분의 경우 동적으로 할당 할 필요가 없습니다. 두 경우 모두

+2

QString을 포함한 대부분의 Qt 데이터 형식은 암시 적 공유를 구현하므로 값으로 사용하는 경우에도 매우 효율적입니다. 또한 Qt에는 스마트 포인터가 있습니다. C++ 11이 광범위하게 구현되면서 다가오는 해에 중요하지는 않을 것입니다. (하지만 지금은 다른 의존성을 추가하지 않아도되므로 합리적인 선택입니다. 스마트 포인터를 제공하기위한 부스트와 같은 프로그램). –

1

currentFile이 null 인 경우 물론 참조 해제되면 충돌이 발생합니다. QString :: null로 설정해도 빈 문자열이 나옵니다. 그것은 당신에게 널 포인터를 제공합니다. 당신이 원하는 것은 다음과 같습니다 : currentFile = "";

Cat Plus에도 좋은 점이 있습니다. 처음에는 포인터가 필요하지 않습니다 (우리에게 보여준 것을 위해).

+0

포인터를 사용하는 것이 현명하다는 것을 간략하게 설명해 주시겠습니까? – Simon

+0

@ Simon : 값과 참조로는 문제를 해결하기에 충분하지 않습니다. 포인터를 사용하지 않는 것이 기본값입니다. –

0

넣어이 생성자

편집에 currentFile = new QString(); :

하고 문자열에 대한 모든 스토리지를 할당 결코, 소멸자이 사실로 인해 가장 아마

+0

작품 - 이제는 정말 어리 석다. 감사합니다. – Simon

+2

오히려 불완전한 대답. 소멸자에서'delete currentFile'을 잊어 버리거나 문자열 대신 포인터를 사용하지 마십시오. –

+0

나는 2 분을 기다려야 할 것이다. ;-) – Simon

2

:는 초기화되지 포인터 역 참조

QString fileName = *currentFile; 
*currentFile = QString::null; 

을.

두 번째 할당은 NULL 포인터를 초기화하지 않습니다. 그것이하는 일은 다음과 같습니다 : currentFile 포인터를 먼저 참조하고 그것이 가리키는 객체를 소멸시키고 그것을 QString :: null 객체로 대체하십시오.

QString :: null은 초기화되지 않은 문자열을 나타내는 데 Qt에서 사용하는 특수 구조이지만 NULL 포인터와 혼동하지 마십시오.

이 같은 포인터를 초기화해야합니다

currentFile = new QString(); 
+0

나중에 delete currentFile을 잊지 마라! –

2

는 사용자가 제공 한 코드에서 모든 포인터를 사용할 필요가 없습니다. (당신이 당신의 편집을 제공하기 전에 코드에서) 그래서, 대신

private: 
    QString currentFile;
QString fileName = currentFile;
currentFile = QString::null;
관련 문제