Почему перегрузка оператора new с помощью std :: string не работает с флагом msvc / MD - PullRequest
0 голосов
/ 20 сентября 2019

У меня есть некоторый код, который выглядит следующим образом.

#include <iostream>
#include <string>
void* operator new(std::size_t n){
    std::cout << "[Allocating " << n << "bytes] ";
    return malloc(n);
}

void operator delete(void* pointer) throw() {
    free(pointer);
}

int main(){

    for(int i = 0; i < 24; i++){
        std::cout << i << ": " << std::string(i, '=') << std::endl;
    }

}

он компилируется и запускается с использованием компилятора gcc, а также запускается при использовании компилятора msvc с установленным флагом / MT или / MTd.однако, если я установлю флаг в / MDd или / MD, программа вылетает.Кажется, он застрял в рекурсии внутри нового оператора.Почему этого не происходит при компиляции и связывании с LIBCMT.lib, который, как я могу судить по документам Microsoft, является разницей между / MT и /MD.

1 Ответ

0 голосов
/ 20 сентября 2019

Вы используете оператор std::cout s << внутри функции замены new.Этот оператор может легко вызвать new для выполнения некоторого распределения, в свою очередь вызывая замену new, которая будет вызывать << и т. Д. И т. П.

Вам следует быть осторожным счто вы делаете в этих функциях.Если вы хотите увидеть, как они называются, вы можете использовать некоторые предварительно выделенные структуры и регистрироваться с ними (или просто увеличивать глобальный счетчик).

Причина, по которой это происходит с одним набором флагов, но не с другим, заключается в том, чтовероятно, из-за различных стратегий распределения, используемых << на основе этих флагов.Они будут частными для реализации, и вы не должны полагаться на них.

...