Макрос для замены нового оператора C++

Это не так, как вы делаете DI (Dependency Injection). Всякий раз, когда вы видите ключевое слово new для службы, вы должны знать, что это неправильно.

Во-первых, вам не нужно ничего передавать в DbContext, этого переопределения OnConfiguring не должно быть, поскольку вы его не используете. Этот вызов заботится об этой конфигурации:

services.AddDbContext<NavigationContext>(options => options.UseSqlServer(Configuration.GetConnectionString("NavigationLoggingDatabase")));

Во-вторых, вы не используете using с внедренными зависимостями, поэтому:

public int Add(TEntity item)
{
    _context.Set<TEntity>().Add(item);
    _context.SaveChanges();
    return item.Id;
}

И, чтобы это работало: [ 1110]

public class SomeController : Controller
{
    private readonly NavigationContext _context;

    public SomeController(NagivationContext context)
    {
        _context = context;
    }
}

И, как последний совет, вы должны действительно, действительно, максимально использовать асинхронные версии методов Entity Framework Core:

public async Task<int> Add(TEntity item)
{
    _context.Set<TEntity>().Add(item);
    await _context.SaveChangesAsync();
    return item.Id;
}
26
задан a3f 31 March 2015 в 01:37
поделиться

7 ответов

Необходимо проверить эту превосходную запись в блоге моего коллеги Calvin. У нас недавно была ситуация, где мы хотели включить этот тип фиксации, чтобы к утечкам ассоциативной памяти со строкой, которая выделила их в сборках диагностики/отладки. Это - интересный прием

http://blogs.msdn.com/calvin_hsia/archive/2009/01/19/9341632.aspx

8
ответ дан JaredPar 28 November 2019 в 07:33
поделиться

3.7.4 продолжительностей Динамической памяти

2 библиотека предоставляет определения по умолчанию для глобальных функций выделения и освобождения. Некоторые глобальные функции выделения и освобождения заменимы (18.5.1). Программа C++ должна предоставить самое большее одно определение заменимой функции выделения или освобождения. Любое такое функциональное определение заменяет версию по умолчанию, обеспеченную в библиотеке (17.6.4.6) [...]

17.6.4.6 Заменяющих функции

  1. , программа C++ А может предоставить определение для любой из восьми подписей функции динамического выделения памяти, объявленных в заголовке (3.7.4, Пункт 18):

    • новый оператор (станд.:: size_t)
    • новый оператор (станд.:: size_t, станд. константы:: nothrow_t&)
    • оператор, новый [] (станд.:: size_t)
    • оператор, новый [] (станд.:: size_t, станд. константы:: nothrow_t&)
    • оператор удаляет (пусто*)
    • , оператор удаляет (пусто*, станд. константы:: nothrow_t&)
    • оператор удаляет [] (пусто*)
    • , оператор удаляет [] (пусто*, станд. константы:: nothrow_t&)

Hope это разъясняет то, что является легальной перегрузкой и что не.

Это может представлять интерес для некоторых здесь:

#define delete cout <<  "delete called at: " << __LINE__ << " of " << __FILE__  << endl, delete 

using namespace std;

void *operator new(size_t size, ostream& o, char *f, unsigned l) {
    o << "new called at: " << l << " of " << f << endl;
    return ::new char[size];
}

int main() {
    int *a = new(cout, __FILE__, __LINE__) int;
    delete a;
}

Чтец Протеста : Что я делаю вот Bad Thing (TM), чтобы сделать - перегрузка нового/удаляющего глобально.

4
ответ дан CB Bailey 28 November 2019 в 07:33
поделиться

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

1
ответ дан TrayMan 28 November 2019 в 07:33
поделиться

Я нашел следующую библиотеку" , nvwa", очень полезный для того, чтобы разыскать новые/удаленные утечки памяти - взглянул на файл "debug_new" для примеров или просто использует его как есть ''.

2
ответ дан James Fisher 28 November 2019 в 07:33
поделиться

Нет, нет никакого пути.

Вы могли сделать это в плохие былые времена malloc()/free(), но не для new.

можно заменить средство выделения памяти путем глобального переопределения new оператор, но Вы не можете ввести специальные переменные, о которых Вы говорите.

-2
ответ дан Jason Cohen 28 November 2019 в 07:33
поделиться

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

1
ответ дан lothar 28 November 2019 в 07:33
поделиться

Вот что я использую:

В new.cpp

const char* __file__ = "unknown";
size_t __line__ = 0;

void* operator new(size_t size) {
    void *ptr = malloc(size);
    record_alloc(ptr,__file__,__line__);
    __file__ = "unknown";
    __line__ = 0;
    return ptr;
}

void delete(void *ptr)
{
   unrecord_alloc(ptr);
   free(ptr);
}

Для компактности я опускаю другие определения new и delete. record_alloc и unrecord_alloc - это функции, которые поддерживают связанный список структур, содержащих ptr, строку и файл).

в new.hpp

extern const char* __file__;
extern size_t __line__;
#define new (__file__=__FILE__,__line__=__LINE__) && 0 ? NULL : new

Для g ++ «new» раскрывается только один раз. Ключ - это «&& 0», что делает его ложным и заставляет использовать настоящее новое. Например,

char *str = new char[100];

расширяется препроцессором до

char *str = (__file__="somefile.c",__line__=some_number) && 0 ? NULL : new char [100];

. Таким образом, записываются номер файла и строки, и вызывается ваша настраиваемая новая функция.

Это работает для любой формы new - до тех пор, пока существует соответствующая форма в new.cpp

23
ответ дан 28 November 2019 в 07:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: