2015-12-07 6 views
-1

Различные источники, похоже, препятствуют типизированным константам в пользу более объектно-ориентированных методов. Например, DelphiBasics, где они описываются как «очень странные» и StackOverflow Question, в которых дается некоторое представление о том, почему они могут использоваться. Вот пример истинной и типизированной константы.Может ли типизированные константы быть источником утечек памяти?

const 
    RESULTS_BASIC1  = $01; // True constant 
    RESULTS_BASIC2: BYTE = $01; // Typed constant 

Я использую Delphi 7 и FastMM4 и утечка одного TCriticalSection в отчетах. После включения подробного файла карты в опциях проекта, трассировки стека FastMM4 показывает что-то вроде этого:

402E58 [StConst][StConst][@GetMem] 
40454B [WinConvert][WinConvert][d_len] 
404926 [Main][Main][EXAMPLE_TYPED_CONSTANT1] 
... 

Если я затем удалить типизированной константой, то же TCriticalSection сообщается как утечку ... на следующей машинке постоянная! После замедления удаления одной типизированной константы за другой я все еще не приближаюсь к «истинному» источнику утечки.

Две смежные вопросы:

1) Может ли наберется константа (которые на самом деле являются переменными с адресом памяти) является истинным источником утечки памяти? Может ли FastMM4 сообщать об утечке по ошибке?

2) Следует ли исключать типизированные константы, и если да, то в чем рекомендуемая альтернатива? Например, скажем, я использую истекшее процессор TickCount (беззнаковое 32-битное целое число):

dwElapsed := (GetTickCount() - m_dwLastFlashCheck); 
if (dwElapsed > 2000) then 
    begin 
    m_dwLastFlashCheck := GetTickCount(); 
    DoSomething(); 
    end; 

кажется естественным, чтобы определить «константа», как в:

RATE_FLASH: DWORD = 2000; 
// ... 
if (dwElapsed > RATE_FLASH) then 
// etc 
+0

Связанный, [утечка строки delphi] (http://stackoverflow.com/q/5423329/576719). –

+1

В последнем вопросе использование типизированной константы не требуется. Достаточная константа, RATE_FLASH = 2000'. Компилятор обычно найдет правильный перевод. В некоторых случаях вы можете использовать 'RATE_FLASH = DWORD (2000)', чтобы сделать его более понятным. –

+0

@ LURD: Правильно! В будущем я буду использовать ваш предложенный «RATE_FLASH = DWORD (2000)», поскольку это кажется ясным и дает истинную константу. – AlainD

ответ

4

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

Ваши постоянные проблемы не являются проблемой. У вас явно есть плохо декодированная трассировка стека. Если вы можете использовать madExcept, например, чтобы декодировать трассировки стека, то я подозреваю, что вы получите лучшие трассировки стека. Также правдоподобно, что неудачная трассировка стека происходит из-за устаревшего файла карты.

Суть в том, что у вас никогда не должно быть адреса данных в качестве обратного адреса в стеке. Таким образом, трассировка стека должна быть ошибочной.


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

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

+0

ОК, рассмотрим использование madExcept. Устанавливайте его, но нужно напоминать себе, как его использовать. – AlainD

+0

Вам нужно заставить FastMM использовать функции трассировки стека. IIRC. –

+0

Вы правы, но AFAICS Я настроил FastMM4 для использования его функций трассировки стека, указав «FullDebugMode» и «RawStackTraces» в файле .inc для FastMM4. Включив эти параметры и подробный файл карты, FastMM4 сообщает о трассе, как указано в вопросе, например. "[Главная] [Главная] [EXAMPLE_TYPED_CONSTANT1]. – AlainD