auto a = new int[0];
Theo [basic.compound.3] , giá trị được lưu trữ a
phải là một trong những điều sau đây:
- Một con trỏ tới một đối tượng (có kiểu
int
)
- Một con trỏ đi qua phần cuối của một đối tượng
- Vô giá trị
- không hợp lệ
Chúng ta có thể loại trừ khả năng đầu tiên vì không có đối tượng thuộc loại được int
xây dựng. Khả năng thứ ba được loại trừ vì C ++ yêu cầu trả về một con trỏ không null (xem [basic.stc.dynamic.allocation.2] ). Do đó, chúng ta chỉ còn hai khả năng: một con trỏ đi qua phần cuối của một đối tượng hoặc một con trỏ không hợp lệ.
Tôi sẽ có khuynh hướng xem a
như một con trỏ quá khứ, nhưng tôi không có một tài liệu tham khảo có uy tín để xác định rõ ràng điều đó. (Tuy nhiên, có một hàm ý mạnh mẽ của điều này trong [basic.stc] , xem làm thế nào bạn có thể delete
con trỏ này.) Vì vậy, tôi sẽ giải trí cả hai khả năng trong câu trả lời này.
Giữa việc khởi tạo và xóa bản sao, bạn có được phép đọc con trỏ tại a + 1
không?
Hành vi không được xác định, như được chỉ định bởi [expr.add.4] , bất kể khả năng nào từ phía trên áp dụng.
Nếu a
là một con trỏ quá khứ, thì nó được coi là trỏ đến phần tử giả định tại chỉ mục 0
của một mảng không có phần tử. Thêm số nguyên j
vào a
chỉ được xác định khi 0≤0+j≤n
, n
kích thước của mảng. Trong trường hợp của chúng tôi, n
bằng không, vì vậy tổng a+j
chỉ được xác định khi j
có 0
. Cụ thể, việc thêm 1
là không xác định.
Nếu a
không hợp lệ, thì chúng tôi hoàn toàn rơi vào "Nếu không, hành vi không được xác định." (Không ngạc nhiên, các trường hợp được xác định chỉ bao gồm các giá trị con trỏ hợp lệ.)
Hơn nữa, ngôn ngữ có cho phép trình biên dịch được đặt a
thành nullptr
không?
Không. Từ [basic.stc.dynamic.allocation.2] đã đề cập ở trên : "Nếu yêu cầu thành công, giá trị được trả về bởi hàm phân bổ có thể thay thế là giá trị con trỏ không null" . Ngoài ra còn có một chú thích gọi ra rằng C ++ (nhưng không phải C) yêu cầu một con trỏ không null để đáp ứng yêu cầu bằng không.
a
chắc chắn (bạn chắc chắn không thể bỏ qua nó).