2008-10-27 22 views

Trả lời

45

Theo tiêu chuẩn hiện hành, mới không bao giờ trả NULL, nó ném một std :: bad_alloc để thay thế. Nếu bạn không muốn mới để ném (theo tiêu chuẩn cũ) nhưng thay vì trả về NULL, bạn nên gọi nó bằng cách postfixing nó với "(std :: nothrow)". ví dụ:

Foo* foo = new (std::nothrow) Foo; 

Tất nhiên, nếu bạn có một toolchain rất cũ hoặc có thể bị hỏng nó có thể không theo tiêu chuẩn.

+0

"Nó không bao giờ trả về NULL" ... sau đó bạn đi trước và mâu thuẫn với chính mình :) using std :: nothrow làm cho phần đầu tiên của bạn statement false :) –

+0

Nó không làm cho nó sai, chỉ là một chút không phù hợp. Các "bình thường" verison mới không bao giờ trả về NULL. – Gorpik

+1

Nó sẽ không làm tổn thương để sửa chữa câu trả lời mặc dù! –

0

Thông thường, không ai kiểm tra việc trả lại mã mới trong mã mới vì Visual Studio giờ đây đã ném theo cách tiêu chuẩn nói.

Trong mã cũ nếu một hack đã được thực hiện để tránh bị ném thì bạn vẫn nên kiểm tra tốt hơn.

+0

Còn câu hỏi ngụ ý rằng môi trường là MS DevStudio thì sao? –

+0

Không có gì. Nhưng nếu Visual Studio đã không nhận được bản sửa lỗi này thì áp phích sẽ ít có khả năng hơn trong tình huống này "Tôi thường không bao giờ thấy thử nghiệm mới trong C++". Vì vậy, tôi đã giải thích nó. –

4

Tất cả phụ thuộc vào phiên bản nào của mã C++. Đặc tả C++ trong một thời gian dài đã tuyên bố rằng, theo mặc định ít nhất, các lỗi trong mới sẽ gây ra ngoại lệ C++, vì vậy bất kỳ mã nào thực hiện kiểm thử sẽ hoàn toàn dư thừa. Hầu hết các chương trình hiện nay cũng nhắm vào các hệ điều hành bộ nhớ ảo, nơi hầu như không thể chạy hết bộ nhớ, và điều kiện hết bộ nhớ quá tệ đến nỗi chỉ cho phép ứng dụng gặp sự cố truy cập NULL tiếp theo. chấm dứt.

Chỉ thực sự trong lập trình nhúng, nơi xử lý ngoại lệ được coi là quá nhiều chi phí và bộ nhớ rất hạn chế, các lập trình viên bận tâm kiểm tra các lỗi mới.

+0

Ghi ngoại lệ và lưu dữ liệu vào đĩa, có thể là cách tốt hơn là chỉ để cho ứng dụng gặp sự cố ... –

+0

Nhưng làm cách nào? Hiện đại C++ có đầy đủ các đối tượng sáng tạo khắp nơi. Khi một "cái mới" thất bại, nó sẽ không thành công. Có nghĩa là một nỗ lực để lưu dữ liệu vào đĩa cũng sẽ thất bại. –

+1

"nơi mà hầu như không thể hết bộ nhớ" Tôi không đồng ý rằng nó dễ dàng hết bộ nhớ ảo trên quy trình 32 bit - trong cửa sổ bạn chỉ nhận được 2 Gig không gian địa chỉ - bất kỳ tên miền nào liên quan đến dữ liệu được lấy mẫu - video, y tế, v.v ... Có thể dễ dàng điền vào hoặc phân đoạn này dẫn đến lỗi phân bổ – morechilli

3

Như trích dẫn here

"Trong trình biên dịch phù hợp với các tiêu chuẩn ISO C++ chuẩn, nếu không có đủ bộ nhớ cho việc phân bổ, mã ném một ngoại lệ kiểu std :: bad_alloc. Tất cả các mã tiếp theo được hủy bỏ cho đến khi lỗi được xử lý trong một khối try-catch hoặc chương trình thoát bất thường. Chương trình không cần kiểm tra giá trị của con trỏ; nếu không có ngoại lệ nào được ném, việc cấp phát thành công. "

7

Tất cả phụ thuộc vào trình chỉnh sửa VC++ của bạn lên phiên bản 6 cho NULL nếu toán tử mới không thành công, trên ứng dụng không MFC. Bây giờ vấn đề trở nên lớn hơn khi bạn sử dụng STL với VC++ 6, vì STL đi kèm với các tiêu chuẩn nó sẽ không bao giờ kiểm tra NULL khi cần bộ nhớ, và đoán điều gì sẽ xảy ra trong điều kiện bộ nhớ thấp. ...

Vì vậy, với mọi người vẫn sử dụng VC++ 6 và STL, hãy kiểm tra bài viết này để khắc phục sự cố. Don't Let Memory Allocation Failures Crash Your Legacy STL Application

3
  1. new ném std::bad_alloc theo mặc định. Nếu bạn sử dụng mặc định, kiểm tra null là lỗi thời, nhưng việc xử lý các ngoại lệ là cần thiết.Hành vi mặc định này phù hợp với mô hình an toàn ngoại lệ C++ - thường cung cấp một đối tượng được xây dựng hoặc không được phân bổ

  2. nếu bạn ghi đè mặc định bằng cách sử dụng new (std::nothrow). "Mới" vừa phân bổ vừa cam kết các trang, do đó bạn có thể hết bộ nhớ, hoặc vì bạn đã hết bộ mô tả trang hoặc do không có bộ nhớ vật lý nào có sẵn

  3. nghiên cứu quản lý bộ nhớ của hệ điều hành của bạn. Máy tham chiếu C/C++ không biết hệ điều hành của bạn quản lý bộ nhớ như thế nào, do đó chỉ dựa vào ngôn ngữ là không an toàn. Ví dụ phân bổ bộ nhớ xấu đi, đọc trên C malloc() + Linux overcommit

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