2013-03-05 10 views
6

Đoạn mã sau có an toàn không, miễn là tôi không đọc bất kỳ phần tử nào trong mảng của cấu trúc mà không cài đặt nó với giá trị thực trước? Cảm ơn.Bạn có thể sao chép dữ liệu chưa được khởi tạo nếu nó không được sử dụng/thiết lập sau không?

const int data_size = 5; 

struct Testing 
{ 
    int data[data_size]; 

    Testing(const int data[data_size]) 
    { 
     std::copy(data, data + data_size, this->data); 
    } 
}; 

int main() 
{ 
    int data[data_size]; 
    data[2] = 57; 

    Testing t(data); 

    t.data[1] = 93; 
} 
+2

Không chắc chắn lý do tại sao bạn muốn thực hiện việc này, nhưng điều đó sẽ an toàn. Rác rác trong thùng rác, nhưng rác không nên rơi ra khỏi thùng rác và bốc mùi lên bộ nhớ xung quanh. –

+2

Với các loại không thể phân chia không đáng kể, rất có thể là không an toàn và chắc chắn là hành vi không xác định. Với các loại có thể gán được tầm thường, nó có thể là * an toàn, trong hầu hết các điều kiện, nhưng chắc chắn vẫn chưa được xác định. –

+0

Xin chào Ben, tôi không hiểu bình luận của bạn. Bạn có ý nghĩa gì với việc chuyển nhượng một cách trivially? –

Trả lời

9

std::copy được định nghĩa là làm *(result + n) = *(first + n) cho mỗi phần tử trong dãy (§25.3.1). Giá trị được đưa ra bởi *(first + n) là một biểu thức giá trị (§5.3.1/1), trong trường hợp của bạn đề cập đến một giá trị chưa được khởi tạo. Vì toán tử gán mong đợi một giá trị gia tăng vì nó là toán hạng bên phải (đây là ill-specified), điều này sẽ dẫn đến việc chuyển đổi giá trị rvalue thành rvalue. Chuyển đổi từ rvalue sang rvalue trên một biểu thức đề cập đến một giá trị chưa được khởi tạo là hành vi không xác định (§4.1):

Nếu đối tượng mà glvalue không phải là đối tượng kiểu T và không phải là đối tượng của loại có nguồn gốc từ T, hoặc nếu đối tượng chưa được khởi tạo, một chương trình yêu cầu chuyển đổi này có hành vi không xác định.

Vì vậy, mã của bạn có hành vi không xác định. Các giải pháp là tất nhiên để khởi tạo các yếu tố của mảng (có lẽ với int data[data_size] = {};).

+0

vì vậy có thể thêm quickfix để thêm memset (dữ liệu, 0, sizeof (dữ liệu)); ngay sau khi khai báo mảng trong main(). – Slava

+3

@Slava: Hoặc chỉ khởi tạo đúng cách. 'int data [data_size] = {};' –

+0

@BenjaminLindley điểm tốt, ngắn hơn nhiều. – Slava

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