2016-07-25 16 views
6

tôi chút nhầm lẫn về C++ mã sau:khởi của một const tĩnh biến

#include <iostream> 

using namespace std; 

void test(const string& str) 
{ 
    static const char * const c = str.c_str(); 
    cout << c << endl; 
} 

int main(int argc, char* argv[]) 
{ 
    test("Hello"); 
    test("Nooo"); 
    return 0; 
} 

Kể từ khi biến c được khai báo là staticconst, nên không này được khởi tạo một lần duy nhất và giữ giá trị ban đầu của nó cho đến khi quá trình hoàn thành? Theo lập luận này, tôi đã mong đợi đầu ra sau đây:

Hello 
Hello 

Nhưng tôi nhận:

Hello 
Nooo 

Bạn có thể làm rõ tại sao giá trị của biến c đã được sửa đổi giữa hai chức năng cuộc gọi mặc dù nó biến số const là gì?

Trả lời

14

Chương trình của bạn có hành vi không xác định.

Khi bạn vượt qua "hello"-test, một đối tượng tạm thời std::string được tạo ra, và từ đó chuỗi c được xây dựng (mà chỉ là một con trỏ đến dữ liệu của đối tượng string).

Khi cuộc gọi chức năng kết thúc, đối tượng std::string tạm thời bị hủy và c trở thành một con trỏ lơ lửng. Sử dụng nó một lần nữa là hành vi không xác định.

Trong trường hợp của bạn, dữ liệu của đối tượng tạm thời thứ hai std::string có cùng địa chỉ bộ nhớ giống với địa chỉ đầu tiên, vì vậy, c trỏ đến dữ liệu đó. Điều này không được đảm bảo.

+0

Thực ra nó không được xác định. ** Dereferencing ** nó không xác định. Vì nó luôn có một địa chỉ hợp lệ khi bị hủy đăng ký, đây là một chương trình hợp lệ. – StoryTeller

+3

@StoryTeller, 'cout << c << endl;' không coi trọng con trỏ. –

+1

@StoryTeller Toán tử đầu ra sử dụng dereferencing. –

1

Bạn có Hành vi không xác định trong mã của mình để những kết quả này có thể thay đổi. UB là bởi vì gọi test("Hello"); tạo ra một tạm thời mà sau đó bạn gán cho biến địa phương tĩnh. Tạm thời này bị hủy sau khi cuộc gọi kết thúc, vì vậy con trỏ trong hàm kiểm tra đang treo lơ lửng. Nếu bạn sử dụng nó thì bạn có hành vi không xác định.

Có thể trình quản lý bộ nhớ sẽ sử dụng lại cùng một vùng bộ nhớ để bạn thấy Hello và Nooo trong kết quả của mình.

Các vấn đề liên quan