2011-11-22 26 views
6

này là khá cường điệu, nhưng là đoạn mã sau "an toàn" (tức là bảo đảm không gây lỗi segmentation):Đang truy cập con trỏ thô sau std :: vector :: bảo lưu an toàn?

std::vector<int> vec(1); // Ensures that &vec[0] is valid 
vec.reserve(100); 
memset(&vec[0], 0x123, sizeof(int)*100); // Safe? 

tôi nhận ra rằng đây là xấu xí - Tôi chỉ muốn biết nếu nó an toàn về mặt kỹ thuật , không đẹp". Tôi đoán cách sử dụng duy nhất của nó có thể là bỏ qua các giá trị được lưu trữ ngoài một chỉ mục đã cho.

Lưu ý! How can I get the address of the buffer allocated by vector::reserve()? bao gồm cùng một chủ đề, nhưng tôi quan tâm nhiều hơn nếu đây là an toàn và nếu có những cạm bẫy làm việc này.

EDIT: Mã gốc sai, thay thế ban đầu memcpy bằng memset.

+1

Ok, điều này quá xấu đến nỗi đau. Tại sao bạn làm việc đó? Bạn không thể đơn giản sử dụng một mảng, nếu bạn thực sự phải? Trong ví dụ này 100 là cố định, vì vậy bạn có thể sử dụng một mảng trên ngăn xếp mà không xóa [] ing ... – Francesco

+2

"Lỗi phân đoạn" là sự kiện theo nền tảng cụ thể. Ngôn ngữ C++ không mô tả nó là gì. Ngôn ngữ chỉ nói cho dù một cái gì đó được xác định, và nếu như vậy, để làm những gì. –

+1

Tôi đã downvoted câu hỏi, không phải vì tôi coi nó là một câu hỏi xấu, nhưng vì bạn không mất đủ thời gian để đảm bảo rằng những gì bạn đang hỏi là những gì bạn muốn hỏi (mã ban đầu và mã trong phiên bản hiện tại là khá khác nhau).-2 điểm rep không nhiều, nhưng nên nhắc bạn trong tương lai cẩn thận hơn một chút, như khi bạn yêu cầu người khác dành thời gian để trả lời cố gắng giúp đỡ, và đó là thời gian bị lãng phí nếu bạn cải cách câu hỏi sau trên. –

Trả lời

16

Không, không an toàn.

Sau reserve(), vectơ được đảm bảo không phân bổ lại dung lượng cho đến khi đạt được capacity().

Tuy nhiên, tiêu chuẩn không cho biết việc triển khai thực hiện vectơ có thể thực hiện với việc lưu trữ giữa size()capacity(). Có lẽ nó có thể được sử dụng cho một số dữ liệu nội bộ - ai biết được? Có lẽ không gian địa chỉ chỉ được dành riêng và không được ánh xạ tới RAM thực tế?

Truy cập các phần tử bên ngoài [0..size) là hành vi không xác định. Có có thể là kiểm tra phần cứng cho điều đó.

+0

upped cho chỉ ra _why_ đây là một ý tưởng tồi: bộ nhớ dành riêng là UB và không có sẵn 'chính thức' thông qua các vector cho đến khi nó đã được 'resize'd hoặc' push'/'emplace'd đến. –

2

Vector-phân bổ lại làm mất hiệu lực hiện con trỏ, tham chiếu, vv Dự trữ thể kích hoạt một tái phân bổ (23.3.6.2, [vector.capacity]) nhưng bạn đang dùng địa chỉ của phần tử đầu tiên sau việc tái phân bổ cuối cùng (mà trong trường hợp này sẽ không có thể xảy ra ở tất cả, nhưng đó là ngoài điểm). Vì vậy, tôi thấy không có vấn đề với mã.

+0

Đã cập nhật câu hỏi của tôi để sử dụng memset thay vì 'memcpy (ví dụ của tôi không chính xác). – larsmoa

2

Lưu ý đầu tiên rằng memset của bạn sẽ cắt bớt 0x123 thành một byte đơn và viết rằng, không viết mẫu bốn byte.

Sau đó, không làm điều đó, chỉ cần sử dụng các container: std::vector<int> vec(100, whatever_value_you_want);

Tuy nhiên để trả lời câu hỏi đó có thể xuất hiện để làm việc đặc biệt với nhiều loại POD nếu trình biên dịch không sử dụng không gian phân bổ cho bất cứ điều gì. Chắc chắn nếu có ai đó gọi resize, insert, push_back vv nó sẽ thổi bay đi bất cứ thứ gì bạn đã ghi vào bộ nhớ và kích cỡ của vectơ cũng sẽ sai. Không có lý do gì để viết mã như vậy.

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