About memory access errors

Memory access errors, such as array-bounds errors, dangling pointers, uninitialized memory reads, and memory allocation errors, are among the most difficult to detect. The symptoms of incorrect memory use typically occur far from the cause of the error and are unpredictable, so that a program that appears to work correctly really works only by accident.

Array bounds errors

When your program writes memory past the bounds of an allocated block, the memory could belong to another data structure in the program, which would become corrupted when it is overwritten. Reading from beyond the memory block might appear less critical because memory is not corrupted. However, the behavior of the program comes to depend on the values accessed, which are unpredictable. If the exact layout of memory is changed, the memory block adjacent to the block for which the reference was intended might be totally different and contain different values.

Purify inserts guard zones around statically and dynamically allocated memory to catch this type of access error. Purify reports an array bounds read (ABR) or an array bounds write (ABW) message at the time it detects the error.

Accessing through dangling pointers

When a dynamically allocated block of memory is freed, the memory is often reallocated to a new data structure in a different part of the program. If a program uses a dangling pointer to read values from a recently-freed memory block, and the freed memory hasn't been reallocated yet, the expected value might still be present. Although the program appears to work, it could fail if the memory allocation pattern changes and the freed memory block is reallocated earlier.

In a threaded program, the reallocation can happen in another thread, in which case the failure becomes dependent upon specific timing issues. For example, the program might fail only on a multi-processor machine where the second processor allocates the memory while the first processor is still accessing it.

Similarly, if a program uses a dangling pointer to write a value to a recently-freed memory block, the program might continue to work. However, if the memory is already being used by another data structure, the write will corrupt that other data structure. The corruption is apparent only later in the run when it's difficult to identify the cause.

Purify tracks freed memory and reports invalid memory accesses as free memory read (FMR) or free memory write (FMW) errors at the time the errors occur.

Uninitialized memory reads

In C and C++, local variables are allocated from memory on the stack at the time the function or block defining the variable is entered. Initially, the variables contain whatever values the stack memory last held, and are considered uninitialized. If your program attempts to use the value of such a variable without first setting it, the value is undefined. Unfortunately, the value is not random, but depends on how that memory was last used. Similarly, memory you get from malloc or new starts out uninitialized.

Purify tracks new memory blocks as they are allocated and reports any attempt to read or use a value from the block before it's initialized as an uninitialized memory read (UMR) error.

Memory allocation errors

If your program incorrectly uses memory-allocation primitives, it might continue to run in spite of the error. However, in this case you risk corrupted heap data structures and failures at a later point in your program's run.

Purify intercepts all calls to memory allocation API functions such as malloc, new, new[], calloc, realloc and related functions, to warn you about their incorrect use. For example, when you use an incorrect function to free memory, such as calling free on memory obtained from new, Purify generates a freeing mismatched memory (FMM) message.

Notes: