2013-05-16 52 views
5

Cả hai lệnh gọi hàm get_string và get_string2 trả về trong phạm vi khi hàm trả về. Không nên đối tượng trả về là một địa chỉ trong bộ nhớ mà đi ra khỏi phạm vi sau khi hàm trả về? Điều này đang sử dụng Visual Studio 2008. Điều này có nên luôn hoạt động không? Tại sao?Con trỏ C++ đến các đối tượng nằm ngoài phạm vi khi hàm trả về - tại sao nó hoạt động?

#include <iostream> 

enum myID { SMALL, MEDIUM, LARGE }; 

const char* get_string(myID id) { 
    switch(id){ 
     case SMALL: return "small"; 
     case MEDIUM: return "medium"; 
     case LARGE: return "large"; 
     default: return "unknown"; 
    } 
} 

const char* get_string2(myID id) { 
    char* s = 0; 
    switch(id){ 
     case SMALL: s = "small"; return s; 
     case MEDIUM: s = "medium"; return s; 
     case LARGE: s = "large"; return s; 
     default: return "unknown"; 
    } 
} 

int main() { 
    std::cout << get_string(SMALL) << std::endl; 
    std::cout << get_string2(SMALL) << std::endl; 
    return 0; 
} 
+0

có thể trùng lặp của [trả về một con trỏ tới một mảng ký tự (hoặc không đổi) (string)?] (Http://stackoverflow.com/questions/4836534/returning-a-pointer-to-a-literal-hoặc -constant-character-array-string) –

Trả lời

11

literals chuỗi là chữ duy nhất mà là lvalues ​​và có thời gian lưu trữ tĩnh. Vì vậy, trả về một con trỏ đến phần tử đầu tiên của một chuỗi ký tự là rất an toàn. So sánh

const char* f1() 
{ 
     return "Hello"; // OK 
} 

const char* f2() 
{ 
     const char s[6] = "Hello"; 
     return s; // Undefined Behavior 
} 


const char* f3() 
{ 
     const char* s = "Hello"; 
     return s; //OK 
} 

Đánh giá từ các ý kiến, câu trả lời này cần một số xây dựng. OK, xem, một chuỗi ký tự được lưu trữ trong bộ nhớ cho đến khi chương trình kết thúc. Trong trường hợp 1 bạn trả về một con trỏ đến nó. Con trỏ đối tượng là còn sống, vì vậy nó là tốt. Trong trường hợp 3, bạn lấy địa chỉ của chữ vào một biến cục bộ và trả về địa chỉ sau bằng bản sao. Bản sao của địa chỉ vẫn trỏ đến một bộ nhớ hợp lệ, do đó, nó là tốt. Tuy nhiên, trong trường hợp thứ hai, chúng tôi sao chép chuỗi ký tự thành một mảng địa phương bị phá hủy khi thoát khỏi hàm. Trả về địa chỉ của biến cục bộ là hành vi không xác định.

Hơn nữa, nếu những gì bạn nghĩ là hành vi undefined thực sự không xác định sau đó bạn không nên ngạc nhiên hoặc vì hành vi không xác định có thể có nghĩa

  • không hoạt động
  • tác phẩm đôi khi
  • luôn hoạt động
  • không vui công cụ không thể giải thích
  • bất cứ điều gì

Vì vậy, nếu một cái gì đó hoạt động nó không có nghĩa là nó OK. Trong trường hợp này, nhưng không phải trong trường hợp chung.

+0

Vì vậy, bởi vì nó là một chuỗi chữ nó không được lưu trữ như là một biến stack? Nó được lưu trữ trong một biến toàn cầu? Bạn có liên kết web với chi tiết về điều này không? –

+0

bạn có muốn giải thích thêm một chút về trường hợp hành vi không xác định không? Tôi chỉ muốn biết – mr5

+0

@ mr5: Xem chỉnh sửa của tôi –

4

Bộ nhớ này không nằm ngoài phạm vi. Đây là các chuỗi ký tự chuỗi, chúng tồn tại mọi lúc trong khi chương trình chạy.

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