5

Quotation:

The test if (allocbuf + ALLOCSIZE - allocp >= n) { checks if there's enough room to satisfy a request for n characters. If there is, the new value of allocp would be at most one beyond the end of allocbuf.

The code which it relates to:

#define ALLOCSIZE 10000 /* size of available space */
static char allocbuf[ALLOCSIZE]; /* storage for alloc */
static char *allocp = allocbuf; /* next free position */

char *alloc(int n)
/* return pointer to n characters */
{
    if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */
        allocp += n;
        return allocp - n; /* old p */
    } else
/* not enough room */
        return 0;
}
void afree(char *p) /* free storage pointed to by p */
{
    if (p >= allocbuf && p < allocbuf + ALLOCSIZE)
        allocp = p;
}

So how can it be beyond the last position in allocbuf? Which in my opinion is allocbuf[9999]

Anything beyond that eg. allocbuf[10000] is incorrect and is a memory leak, am I right?


The second part of the question - I though that afree function according to its name is deleting the value saved at particular places in an array. However as I can see it just moves the "recording head" just a few places to the left of an array? Data saved there remains untouched.

Peter Cerba
  • 806
  • 4
  • 14
  • 26
  • 1
    If `allocp` points to `allocbuf[10000]`, this means that the storage is used completely (the last slice had exactly `n` entries) and hence a subsequent `alloc()` will return `0`. The quotation does not say that this "illegal" pointer is allowed to be used, and it is indeed not returned from `alloc()`. – evnu Aug 14 '12 at 15:24
  • 2
    FYI, accessing memory beyond which was allocated for you is an overrun, not a memory leak. A memory leak is loosing track of the allocated memory so you cannot free that memory later on. – Jeff Mercado Aug 18 '12 at 18:19

2 Answers2

5

allocp should always point to the last free memory position but when there is no memory positions free it will be one beyond the end of allocbuf.

Consider the situation when there is only one single memory cell left in the buffer: allocp will point to allocbuffer[9999] since that is the last free memory cell. Now when you make the function call alloc(1) the test

allocbuf + ALLOCSIZE - allocp >= n

will return true as it should since you are trying to allocate one char and there is exactly one char left. Then the very last memory position will be allocated. Now allocbuf - allocp == ALLOCSIZE and is one beyond the end of allocbuf. But in that case the above mentioned test will always return false and thus no memory will ever be accessed beyond the scope of allocbuf.


About your question regarding afree: The initial value of the memory returned by malloc is undefined. This means that you can never make any assumptions about it and must overwrite it before use. Therefore afree does not have to delete any data contrary to what you're assuming. It is perfectly fine for it to simply mark it as no longer in use and available for future allocation.

On a side note there is a function very similar to malloc named calloc which after allocating the requested memory block initializes it all to zero.

paldepind
  • 4,680
  • 3
  • 31
  • 36
2

Regarding the second part of your question: memory management functions like afree() or the C library free() don't typically zero or clear memory. They just make it available for reuse. This is good because you don't pay the performance cost. Unfortunately, it can mask bugs such as using memory you no longer own.

Some heap managers may zero memory or fill it with special values when you call free() for security reasons or to assist debugging. This isn't required by the standard and you'd have to specifically enable this behavior.

Blastfurnace
  • 18,411
  • 56
  • 55
  • 70