2009-10-11 4 views
0

이 오류가 왜 나타나는지 간단히 알 수 없습니다.이 디버깅 도와주세요 - 'const char *'에서 'char *'로의 무효 변환

Widget.cpp: In constructor 'Widget::Widget(Generic, char*, int, int, int, QObject*)': 
Widget.cpp:13: error: invalid conversion from 'const char*' to 'char*' 

위젯의 생성자 측면에서 'const char *'가 없습니다.

class Widget: public QObject { 
    Q_OBJECT 
    Q_PROPERTY(char *col READ getCol WRITE setCol) 
    Q_PROPERTY(char *row READ getRow WRITE setRow) 
    Generic visitor; 
    char *_name; 
    char *_widget_base; 
    int _row; 
    int _col; 
    int _type; 
    public: 
    Widget(Generic visitor, char *name, int row, int col, int type, QObject *parent); 
    char* widgetBase() const; 
    QString getCol() const; 
    void setCol(const QString &col); 
    QString getRow() const; 
    void setRow(const QString &row); 

}; 

Widget::Widget(Generic v, char *name, int row, int col, int type, 
    QObject *parent = 0) { 
    visitor = v; 
    std::string str(name); 
    int pos1 = str.find(":"); 
    int pos2 = str.rfind(":"); 
    _widget_base = str.substr(pos1, pos2-pos1).c_str(); 
    _name = name; 
    _row = row; 
    _col = col; 
    _type = type; 
} 
+0

어떤 행이 13 행입니까? – JesperE

답변

5

이 당신의 코드는 몇 가지 다른 문제를 가지고하는 const char * 값이 이미 대답 된 컴파일러 오류, 저쪽에

str.substr(pos1, pos2-pos1).c_str(); 
4

입니다.

: (. 적어도 당신이 게시 된 코드를 가정하는 것은 실제로 프로젝트에서 사용중인 근처 또는 정확히)

당신이 가리키는 const 포인터로 _widget_base을 변경하더라도,이 코드 줄은 문제가

_widget_base = str.substr(pos1, pos2-pos1).c_str(); 

substr은 임시 문자열 개체를 반환합니다. c_str()의 결과는 여전히 임시 문자열에 의해 소유됩니다. 그리고 그 라인이 쓰여지는 방식으로, 임시 문자열 객체는 라인이 실행 된 후에 파괴 될 것입니다. 따라서 문제는 _widget_base이 삭제되고 언제든지 다시 사용될 수있는 메모리 영역을 가리키고 있다는 것입니다.

위젯의 생성자에 전달하는 내용에 따라 _name과 비슷한 문제가있을 수도 있습니다.

그래서 당신은 어떤 다른 물체에 의해 관리되지 않도록 동적으로 자신을 메모리를 할당 _widget_base_name

1)와 세 가지 중 하나를 수행 할 수있다.

std::string temp = str.substr(pos1, pos2-pos1); 
_widget_base = new char[temp.length()+1]; 
strcpy(_widget_base, temp.c_str()); 

물론 위젯의 소멸자에서이 메모리를 삭제해야합니다. 또한 위젯이있는 동안이 값을 변경할 수있는 경우 재 할당 할 수도 있습니다.

2) 이러한 멤버 변수를 포인터 대신 문자 배열로 만듭니다. 그렇게하면 메모리가 위젯의 영구적 인 부분이므로 관리 할 필요가 없습니다. 물론 배열의 크기가 얼마나 큰지를 결정해야합니다.

char _name[a big enough value]; 
char _widget_base[a big enough value]; 

다음 :

std::string temp = str.substr(pos1, pos2-pos1); 
strcpy(_widget_base, temp.c_str()); 

3) 그 멤버 변수 문자열 개체를 확인합니다.

std::string _name; 
std::string _widget_base; 

다음 : 그것은 가장 강력하고 오류에 적어도 경향이 있기 때문에

_widget_base = str.substr(pos1, pos2-pos1); 

이 방법이 가장 바람직하다. 직접 관리 할 메모리가없고 보유하기에는 너무 큰 값에 대해 걱정할 필요가 없습니다.

관련 문제