 <p>You need to initialize your new structure with zeros. GetMem does not zero the allocated memory, so the fields of your record initially contain random garbage. You need to call</p> <p><code>FillChar(newItem^, sizeof(TAccessoryItem), 0)</code> </p> <p>after the GetMem, before using the record.</p> <p>Here's why: When you assign to the string field of the newly allocated but uninitialized record, the RTL sees that the destination string field is not null (contains a garbage pointer) and attempts to dereference the string to decrement its ref count before assigning the new string value to the field. This is necessary on every assignment to a string field or variable so that the previous string value will be freed if nothing else is using it before a new value is assigned to the string field or variable.</p> <p>Since the pointer is garbage, you get an access violation... if you're lucky. It is possible that the random garbage pointer could coincidentally be a value that points into an allocated address range in your process. If that were to happen, you would not get an AV at the point of assignment, but would likely get a much worse and far more mysterious crash later in program execution because this string assignment to an uninitialized variable has altered memory somewhere else in your process inappropriately.</p> <p>Whenever you're dealing with memory pointers directly and the type you're allocating contains compiler managed fields, you need to be very careful to initialize and dispose the type so that the compiler managed fields get initialized and disposed of correctly.</p> <p>The best way to allocate records in Delphi is to use the New() function:</p> <pre><code>New(newItem); </code></pre> <p>The compiler will infer the allocation size from the type of the pointer (sizeof what the pointer type points to), allocate the memory, and initialize all the fields appropriately for you.</p> <p>The corresponding deallocator is the Dispose() function:</p> <pre><code>Dispose(newItem); </code></pre> <p>This will make sure that all the compiler-managed fields of the record are disposed of correctly in addition to freeing the memory used by the record itself. </p> <p>If you just FreeMem(newItem), you will leak memory because the memory occupied by the strings and other compiler managed fields in that record will not be released.</p> <p>Compiler managed types include long strings ("String", not "string[10]"), wide strings, variants, interfaces, and probably something I've forgotten.</p> <p>One way to think about is this: GetMem/FreeMem simply allocate and release blocks of memory. They know nothing about how that block will be used. New and Dispose, though, are "aware" of the type you're allocating or freeing memory for, so they will do any additional work to make sure that all the internal housekeeping is taken care of automatically. </p> <p>In general, it's best to avoid GetMem/FreeMem unless all you really need is a raw block of memory with no type semantics associated with it.</p>