2014-08-31 19 views
6

Tôi đang cố gắng tìm hiểu về các vùng bộ nhớ trong C++ để có tốc độ và khả năng gỡ lỗi tốt hơn. Tôi đã theo dõi cách tiếp cận được tìm thấy ở đây: http://oroboro.com/overloading-operator-new/. Vì vậy, tôi đã quá tải new, new[], delete, và delete[] như thế này:Xóa quá tải toàn cầu [] không được gọi trong thư viện của bên thứ ba

inline void* operator new  (size_t size) { return myAlloc(size); } 
inline void* operator new[] (size_t size) { return myAlloc(size); } 
inline void operator delete (void* ptr ) { myFree(ptr); } 
inline void operator delete[](void* ptr ) { myFree(ptr); } 

Tôi thích rằng thư viện của bên thứ ba đang hướng đến phiên bản này của new, nhưng tôi chạy vào một vấn đề. Tôi đang tạo một ứng dụng DirectX sử dụng DXUT. Tôi biên dịch DXUT tách biệt khỏi dự án của tôi. Cuối cùng nó gọi:

std::unique_ptr<D3D11_SUBRESOURCE_DATA[]> initData(new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ]); 

Khi con trỏ độc đáo này đi ra khỏi phạm vi, nó bị treo trên một cuộc gọi đến delete[] _Ptr, mà không đi qua nhà khai thác quá tải của tôi. Tôi đã thử gỡ lỗi triển khai pool bộ nhớ của mình bằng cách thêm một số int* dummy = new int[10]; delete[] dummy; trong số main. Xây dựng dự án đã đưa ra một lỗi, nhưng tòa nhà sạch sẽ hoạt động tốt. Trước sự ngạc nhiên của tôi, mọi thứ đã hoạt động, kể cả dòng DXUT đã bị hỏng!

Câu hỏi 1: Chính xác điều gì đã xảy ra khi tôi thêm dòng gỡ lỗi đã khắc phục sự cố? Tôi đoán vì lý do nào đó mà toán tử delete [] của tôi không được biết đến cho đến khi tôi gọi nó trong mã ứng dụng của riêng mình? Điều này có được đảm bảo để khắc phục sự cố hoặc nó chỉ là may mắn không?

Câu hỏi 2: Tôi nhận thấy rằng new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] không gọi trực tiếp số operator new[] của tôi, nhưng cuối cùng được gọi là operator new (không có dấu ngoặc vuông). Nó vẫn gọi toán tử delete[] trên con trỏ. Điều này có gây ra vấn đề không? Tôi có phải thêm quá tải thích hợp sao cho số operator new[] của tôi được gọi hoặc hành vi này có ổn không?

Để tham khảo, các operator new[] quá tải mà được gọi là:

void * __CRTDECL operator new[](::size_t count, const std::nothrow_t& x) 
_THROW0() 
{ // Try to allocate count bytes for an array 
    return (operator new(count, x)); 
} 

Trả lời

4

Câu hỏi 1: Chính xác những gì đã xảy ra khi tôi đã thêm dòng gỡ lỗi rằng cố định vấn đề này? Tôi đoán vì lý do nào đó mà toán tử xóa [] của tôi không phải là được biết cho đến khi tôi gọi nó trong mã ứng dụng của riêng tôi? Điều này có được đảm bảo để khắc phục sự cố hoặc chỉ là sự may mắn không?

§3.2 [basic.def.odr]/p4:

Một chức năng inline sẽ được xác định trong mỗi đơn vị dịch trong đó nó là ODR-sử dụng.

Có vẻ như rằng trình biên dịch của bạn không tạo mã cho toàn cầu operator delete[] vì nó không được sử dụng trong đơn vị dịch chính của bạn và được đánh dấu inline (có nghĩa là trình biên dịch có thể giả định rằng bất kỳ đơn vị dịch thuật có sử dụng chúng sẽ có một định nghĩa của chúng). Tuy nhiên, thư viện được biên dịch riêng của bạn không có định nghĩa về các hàm đó và bạn sẽ sử dụng các hàm mặc định từ thư viện chuẩn. Đặt chúng không phải là inline sẽ khắc phục được sự cố.

Câu hỏi 2: Tôi nhận thấy rằng các new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] không gọi operator new[] trực tiếp, nhưng cuối cùng gọi operator new (không dấu ngoặc) của tôi của tôi.Nó vẫn gọi toán tử delete[] trên con trỏ. Có phải điều này gây ra sự cố không? Tôi có phải thêm quá tải thích hợp như vậy rằng operator new[] của tôi được gọi hoặc hành vi này có ổn không?

Các phiên bản mặc định của cả hai ném và nonthrowing phiên bản của operator new [], cũng như các phiên bản nonthrowing của operator new, được quy định để gọi phiên bản ném của operator new để có được bộ nhớ. Vì vậy, bạn được an toàn ở đó. Tuy nhiên, các định nghĩa của operator new có thể sai. Họ phải trả về một con trỏ hợp lệ hoặc ném một ngoại lệ. Trả về một con trỏ null không được phép.

+0

Xóa nội tuyến và đặt mã vào tệp triển khai thay vì tiêu đề đã hoạt động! Tôi tự hỏi tại sao liên kết tôi sao chép từ đó không đề cập gì về nó. – DSM

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