2012-03-13 33 views
12

Tôi đã cố gắng kiểm tra bad_alloc ngoại lệ bằng cách chuyển một số đối số phủ định đến new[]. Khi vượt qua các số âm nhỏ tôi nhận được những gì tôi mong đợi - một bad_alloc. Tuy nhiên, khi đi qua -1, tôi có thể thấy rằng đối tượng của tôi được tạo hàng nghìn lần (tôi in bộ đếm tĩnh trong hàm tạo) và ứng dụng chấm dứt bằng segfault.Tại sao [-1] mới tạo ra segfault, trong khi [-2] mới ném bad_alloc?

new[] chuyển đổi ký số nguyên để size_t, vì vậy -1 là max của size_t-2maximum - 1 và vân vân.

Vậy tại sao new[] ném ngoại lệ khi nhận được một số lượng lớn, nhưng cố gắng phân bổ khi nhận được tối đa size_t? Sự khác biệt giữa 1111...11111...0 cho new[] là gì? :)

Cảm ơn trước!

+2

Phiên bản/trình điều khiển/trình biên dịch/trình biên dịch nào ... – xanatos

+0

Thời gian đó tôi đã bỏ lỡ câu trả lời vì StackOverflow không gửi cho tôi bất kỳ thông báo nào, và bây giờ tôi không thể tái tạo vấn đề ... Tôi rất tiếc vì tôi đã không tạo ra các bãi lõi và không điều tra nó ... Bây giờ tôi không thể tái tạo vấn đề - đi qua -1 đến 'mới' dường như làm việc và ném ngoại lệ, trong khi vượt qua tối đa int phân bổ rất nhiều đối tượng nhưng không segfault. Tôi bắt đầu nghĩ rằng vấn đề là ở một nơi khác ... Tôi đưa ra một điểm cộng với Mystical để anh ta thử. – flyjohny

Trả lời

17

Dưới đây là đoán hoang dã của tôi:

Trong rất nhiều sự bổ sung, cấp phát sẽ đặt một số siêu dữ liệu bên cạnh các khu vực được giao.
(Ví dụ: kích thước phân bổ.) Vì vậy, bạn đang thực sự phân bổ nhiều hơn những gì bạn đã yêu cầu.

Giả sử size_t là 32 bit. Biên dịch cho 32-bit.


Khi bạn làm:

int *array = new int[-1]; 

Các -1 trở thành -1 * 4 bytes = 4294967292 (sau khi tràn). Nhưng nếu việc thực hiện cấp phát đặt 4 byte siêu dữ liệu bên cạnh vùng được phân bổ. Kích thước thực tế trở thành:

4294967292 + 4 bytes = 0 bytes (after overflow) 

Vì vậy, 0 byte thực sự được phân bổ.

Khi bạn cố gắng truy cập vào bộ nhớ, bạn sẽ phân biệt ngay khi bạn thoát ra ngoài giới hạn ngay lập tức.


Bây giờ giả sử bạn làm:

int *array = new int[-2]; 

Các -2 trở thành -2 * 4 bytes = 4294967288 (sau khi tràn). Nối 4 byte của siêu dữ liệu và bạn nhận được 4294967288 + 4 = 4294967292.

Khi người cấp phát yêu cầu 4294967292 byte từ hệ điều hành, nó bị từ chối. Vì vậy, nó ném bad_alloc.


Vì vậy, về cơ bản, nó có thể là -1-2 nên sự khác biệt giữa hay không nó sẽ tràn sau khi cấp phát gắn thêm siêu dữ liệu của nó.

+0

Tôi chưa bao giờ thấy việc thực hiện lỗi như vậy trong tự nhiên mặc dù – PlasmaHH

+0

+1. "Khi bạn cố gắng truy cập bộ nhớ" - "bạn" là 'new []' chuyển sang vòng lặp qua các phần tử, nó cho rằng nó được cấp không gian cho, gọi vị trí 'new' để gọi hàm tạo trên mỗi .... –

+0

@ PlasmaHH Đó cũng là những gì tôi đang nghĩ. Tôi đang cố gắng tìm một nguồn cho tôi biết liệu bất kỳ điều nào trong số này là hành vi không xác định. Nhưng tôi chưa tìm thấy gì cả. – Mysticial

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