2010-08-11 33 views
9

Mã dưới đây dự kiến ​​sẽ in "kevin" Nhưng, nó đang in giá trị rác. Tôi đã kiểm tra trong trình sửa lỗi. Con trỏ được trả về bởi lệnh "operator char *" không hợp lệ. Bất kỳ ý tưởng?"operator char *" issue

class Wrapper 
{ 
private: 
    char* _data; 

public: 

    Wrapper(const char* input) 
    { 
     int length = strlen(input) + 1; 
     _data = new char[length]; 
     strcpy_s(_data, length, input); 
    } 

    ~Wrapper() 
    { 
     delete[] _data; 
    } 

    operator char*() 
    { 
     return _data; 
    } 
}; 

int main() 
{ 
    char* username = Wrapper("kevin"); 
    printf(username); 
    return 0; 
} 
+6

Đề xuất đầu tiên của tôi là chỉ sử dụng std :: string vì bạn rõ ràng đang sử dụng C++. –

+0

tại sao bạn chỉnh sửa thẻ con trỏ tôi đã thêm? – James

+0

Hãy nhớ rằng bạn thường nên tránh chuyển đổi ngầm. (Và tất nhiên, sử dụng 'std :: vector', hoặc' std :: string', vv) – GManNickG

Trả lời

15

Vấn đề là đối tượng Wrapper của bạn đang được xây dựng dưới dạng tạm thời và bị hủy ngay lập tức. Thông qua các operator char* bạn đang trở về một con trỏ vào bộ nhớ đã bị xóa bởi các đối tượng Wrapper khi nó đã bị phá hủy.

Để làm cho nó làm việc:

Wrapper wrapper("Kevin"); 
char* username = wrapper; 
+1

Cảm ơn. Điều đó thật nhanh chóng. –

+2

@ sankaran1984 Làm cho anh ta/cô ấy một ưu tiên và chấp nhận câu trả lời, đó là dấu kiểm lớn ở bên trái. = P – James

+1

Có thể là tốt đẹp cho người trả lời để upvote một câu hỏi cũng được thể hiện từ một SO newbie quá. –

4

dòng này:

char* username = Wrapper("kevin"); 

tạo ra một đối tượng Wrapper không tên được ngay lập tức bị phá hủy, để lại trỏ trỏ của bạn ở không có gì. Bạn cần phải đặt tên cho đối tượng bao bọc hoặc không viết mã như vậy. Điều này sẽ làm việc:

Wrapper w("kevin"); 
char* username = w; 
printf("%s", username); 
4

Con trỏ bạn đang trở về đã được xóa bởi destructor Wrapper ngay sau khi nó đi ra khỏi phạm vi ở phần cuối của báo cáo kết quả đầu tiên - trước khi printf.
Trong một số trường hợp, lỗi này có thể được che đậy vì bộ nhớ có thể không được lấy lại ngay lập tức và giá trị "trông" OK mặc dù nó không còn hợp lệ nữa. Một số công cụ có thể giúp phát hiện điều này.

1

Lệnh này tạo một Wrapper đối tượng tạm thời:

char* username = Wrapper("kevin"); 

Vào cuối báo cáo kết quả, ("đầy đủ khái niệm") đối tượng Wrapper bị phá hủy. Bạn bị bỏ lại với một con trỏ lơ lửng (tức là, điểm mà nó trỏ vào đã bị xóa).

Trả về một con trỏ (hoặc tham chiếu) đến dữ liệu nội bộ của đối tượng thường nguy hiểm và nên tránh khi nào hợp lý. Trong mọi trường hợp, bạn có nghĩ rằng có đủ các lớp chuỗi trên thế giới không? Bạn có thực sự cần phải viết khác?