简体   繁体   中英

C: Stack implementation of malloc and free

I am reading K&R pointers section 5.4 where a stack implementation of malloc() and free() are done. I am using gdb to debug the code, and the alloc() part is working as expected. But for the afree() part, the pointers are still pointing to the same location as before. Here is the code :

#include <stdio.h>
#define ALLOCSIZE 10000

static char allocbuf[ALLOCSIZE];
static char* allocp = allocbuf;

char* alloc(int n)
{
    if(allocbuf + ALLOCSIZE - allocp >= n)
    {   
        allocp += n;
        return (allocp - n); 
    }   
    else
        return 0;
}


void afree(char* p)
{
    if(p >= allocbuf && p < allocbuf + ALLOCSIZE)
        allocp = p;
}


int main()
{
    char* a = alloc(10);
    a = "ayushnair";
    char*b = alloc(5);
    b = "snea";
    printf("%p    %p\n", a, b); 
    afree(b);
    afree(a);
    printf("%p    %p\n", a, b); 
    return 0;
}

New allocation

allocp 0x601080

after char* a = alloc(10);

allocp 0x60108a

after char* b = alloc(5);

allocp 0x60108f

after afree(b);

allocp 0x60108f

after afree(a);

allocp 0x60108f

allocp still points to 0x60108f . Why does it not update according to the code?

In your code, by saying

a = "ayushnair";

you're not storing the "ayushnair" into the memory pointed by a . The "ayushnair" is a string literal and by saying

a = "ayushnair";

you're storing the base address of the string literal into a . This way, you're essentially overwriting the returned pointer by the call to alloc() .

This is not something you want. You may need to use strcpy() to copy the string literal into the returned pointer.

That said, as per the current code, later by calling

afree(b);
afree(a);

you're invoking undefined behavior as you're trying to comapre pointers that do not point to the same object.

Quoting C11 , chapter §6.5.8, Relational operators

When two pointers are compared , the result depends on the relative locations in the address space of the objects pointed to. If two pointers to object types both point to the same object, or both point one past the last element of the same array object, they compare equal. If the objects pointed to are members of the same aggregate object, pointers to structure members declared later compare greater than pointers to members declared earlier in the structure, and pointers to array elements with larger subscript values compare greater than pointers to elements of the same array with lower subscript values. All pointers to members of the same union object compare equal. If the expression P points to an element of an array object and the expression Q points to the last element of the same array object, the pointer expression Q+1 compares greater than P. In all other cases, the behavior is undefined.

char* a = alloc(10);

This "allocates" memory from allocbuf , and assigns the pointer to that memory to a .

a = "ayushnair";

This assigns a different pointer to a -- one that points to the string literal "ayushnair" , which is not in allocbuf but somewhere else in memory entirely.

From here on onward your program is just getting more and more confused (especially since you make a similar mistake with b ). The call to afree( a ) makes no sense since a is no longer pointing to what alloc() returned, and the comparison done by afree() actually invokes undefined behaviour as Sourav Ghosh pointed out -- but the error is the a = "ayushnair" (and the similar assignment to b ).


The language C has no concept of a "string object", just a convention that a pointer to a sequence of char that ends with a '\\0' is called a "string" and has some support functions. A suitable definition of the operator = to mean "copy the contents" is not part of those support functions.

What you wanted to do was:

char * a = alloc( 10 );
strcpy( a, "ayushnair" );

That would copy from the string literal to the memory pointed to by a .


So, bottom line, your problem is not about logical or comparison operators, and not about arrays -- it's about pointers and strings. I hope I was able to clarify a bit.

It does not update pointer(on afee) as this algorithm of mememory allocator is progressive and has "no memory" of previuosly allocated memory parts. Thus returns just pointer to unused memory. After allocating ALLOCSIZE it will not be possible to allocate more mem. Most memory allocators make some assumptions about consumed memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM