Khi biên dịch với MINGW gcc, toán tử mới bị quá tải không được gọi cho std :: string


8

Chương trình này (được biên dịch với tùy chọn -std=c++17)

#include <stdio.h>
#include <string>
void* operator new(std::size_t nrOfBytes) {
    printf("allocate %zd bytes on heap\n", nrOfBytes);
    void* p = malloc(nrOfBytes);
    if (p) {
        return p;
    } else {
       throw std::bad_alloc{};
    }
}
int main() {
    // new operator is called when compiled with Clang or MSVS or GCC 
    int* i = new int;
    delete i;
    // new operator is not called when compiled with GCC
    // but is called with Clang and MSVS 
    std::string str(2000, 'x');
    return 0;
}

khi được biên dịch bằng Clang hoặc MSVS, hãy in:

phân bổ 4 byte trên heap

phân bổ byte 2016 trên heap

Tuy nhiên, khi được biên dịch bằng GCC (Phiên bản 9.2.0 do MSYS cung cấp trên Windows), nó chỉ in:

phân bổ 4 byte trên heap

Tôi biết về tối ưu hóa chuỗi ngắn trong GCC / libc ++, nhưng không phải 2000 ký tự quá nhiều cho một chuỗi ngắn? Đây có phải là vấn đề của SSO không?


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Samuel Liew

Câu trả lời:


4

Dường như GCC không (hoặc không thể?) Thực hiện thay thế toàn cầu operator newoperator deletechính xác khi các thư viện động có liên quan trên Windows.

Xem báo cáo lỗi, ví dụ 77726 , 8212281413 .

Trong trường hợp của bạn std::string, hàm tạo và / hoặc std::allocator<char>::allocatedường như được đặt trong thư viện động của thư viện chuẩn, do đó, hàm operator newsử dụng không được thay thế chính xác.


1
Để làm rõ hơn: hành vi này chỉ được quan sát thấy khi sử dụng GCC với libc ++ trên Windows được cung cấp bởi MSYS / MINGW. Mọi phiên bản GCC / libstdc ++ trên Ubuntu tôi đều có thể kiểm tra hoạt động chính xác như các chương trình được biên dịch bằng Clang hoặc MSVS. Hơn nữa, rõ ràng đây không phải là trường hợp của SSO khi được biên dịch với GCC, như sizeof(str)sản lượng 32.
Angle.Brquet

@ Angle.Brquet Bạn có nghĩa là libstdc ++ thay vì libc ++?
quả óc chó

Tôi đoán nó được gọi là libc ++ trong MINGW
Angle.Brquet

@ Angle.Brquet libc ++ thường đề cập đến việc triển khai thư viện chuẩn của dự án LLVM cho tiếng kêu. Tôi không nghĩ gcc có thể sử dụng nó, mingw hay không. Nhưng tôi có thể sai ở đây.
quả óc chó

@ Angle.Brquet Tôi đoán bạn có thể xác minh xem bạn đang sử dụng libstdc ++ hay libc ++ bằng các câu trả lời trong câu hỏi này .
quả óc chó
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.