Освобождение памяти выделяется в другом DLL

Вот обычно, как выбрать несколько столбцов из подзапроса:

SELECT
     A.SalesOrderID,
     A.OrderDate,
     SQ.Max_Foo,
     SQ.Max_Foo2
FROM
     A
LEFT OUTER JOIN
     (
     SELECT
          B.SalesOrderID,
          MAX(B.Foo) AS Max_Foo,
          MAX(B.Foo2) AS Max_Foo2
     FROM
          B
     GROUP BY
          B.SalesOrderID
     ) AS SQ ON SQ.SalesOrderID = A.SalesOrderID

, Если то, что Вы в конечном счете пытаетесь сделать, получают значения от строки с самым высоким значением для Foo (а не макс. из Foo и макс. из Foo2 - который НЕ является тем же самым), тогда, следующее будет обычно работать лучше, чем подзапрос:

SELECT
     A.SalesOrderID,
     A.OrderDate,
     B1.Foo,
     B1.Foo2
FROM
     A
LEFT OUTER JOIN B AS B1 ON
     B1.SalesOrderID = A.SalesOrderID
LEFT OUTER JOIN B AS B2 ON
     B2.SalesOrderID = A.SalesOrderID AND
     B2.Foo > B1.Foo
WHERE
     B2.SalesOrderID IS NULL

Вы в основном говорите, даете мне строку от B, где я не могу найти никакую другую строку от B с тем же SalesOrderID и большим Foo.

9
задан Peter Mortensen 3 February 2013 в 23:25
поделиться

3 ответа

Как уже сказал Шон, сборка релиза просто игнорирует этот оператор удаления, поэтому лучшее, на что вы можете надеяться, - это утечка памяти.

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

Обратной стороной является то, что вам необходимо установить систему времени выполнения вместе с вашим приложением (для этого Microsoft предлагает установщик). Он будет отлично работать на вашей машине разработки, поскольку Visual Studio устанавливает и эту систему времени выполнения, но на недавно установленной машине он будет сообщать об отсутствующих файлах DLL.

12
ответ дан 4 December 2019 в 07:23
поделиться

Most likely, the release build has the same problem, but release builds don't assert. They just ignore the problem. You might never see an issue. Or you might see data corruption. Or you might see a crash. Maybe only your users will experience bugs that you are simply not able to reproduce.

Don't ignore CRT assertions.

You should always use the appropriate deallocator (the one that matches the allocator used to begin with). If you are using static CRT libraries in your DLL files, the DLL files are using different heaps. You can not deallocate memory across heaps. Allocate and deallocate a block of memory using the same heap.

If you are using shared CRT libraries in your DLL files, then they should be using the same heap and you can allocate in one DLL file and deallocate in another.

7
ответ дан 4 December 2019 в 07:23
поделиться

Это проблема, только если приложение или один (или несколько) файлов DLL связаны со статической версией стандартной библиотеки. Это было решено около десяти лет назад, когда MS выпустила версию стандартной библиотеки с разделяемой библиотекой. Это связано с тем, что каждая версия стандартной библиотеки будет создавать собственную внутреннюю кучу, и, следовательно, с несколькими кучами вы должны освободить память до правильной кучи. Используя общую версию стандартной библиотеки, все они используют одну и ту же кучу.

В настоящее время это стандартная практика для приложения, и все файлы DLL должны быть построены для использования динамической версии стандартной библиотеки.

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

5
ответ дан 4 December 2019 в 07:23
поделиться
Другие вопросы по тегам:

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