开发者

Is there some "free-able" memory

int main()
{
    char *s1, *sTemp;

    s1 = (char*)malloc(sizeof(char)*7);
    *(s1 + 0) = 'a';
    *(s1 + 1) = 'b';
    *(s1 + 2) = 'c';
    *(s1 + 3) = 'd';
    *(s1 + 4) = 'e';
    *(s1 + 5) = 'f';
    *(s1 + 6) = '\0';

    sTemp = (s1 + 3);

    free(sTemp); // shud delete d onwards. But it doesn't !!

    return 0;
}

Hello,

In the C above code sTemp should point to the 3rd cell beyond s1 ( occupied by 'd') So on calling free(sTemp) i expect to have something deleted from this location onwards.

( I purposely mention 'something' as the motive of my experiment initially was to find out till which location the free() ing works )

However i recieve a SIGABRT at the free().

How does free() know that this is not the start of the chunk. and correspondingly can we free up memory only from start of chunks? [ are they only the free-able pointers that free() can accept?? ]

Looking forwar开发者_开发百科d to replies :)


From the man pages

free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behaviour occurs.

Source: http://linux.die.net/man/3/free


About the actual question "how does free know...":

free knows that it is not at the start of the chunk because it maintains metadata that you don't know about. If you think about it, that's necessarily so, because otherwise it could never know how much memory to free, given only an address.

It is not specified how exactly the runtime keeps book of allocation sizes, only that you must never pass any pointer to free that did not come from a function of the malloc family.

Usually this works by malloc allocating a little more memory than needed[1] and writing some metadata in memory preceding the address that is returned. free then just looks at e.g. ptr[-8] or whatever (implementation detail!) to read this metadata.
It can then optionally do some consistency checks, and can determine the size of the memory block (one trivial consistency check that is probably always done is checking proper alignment of the pointer).

Having mentioned that, please please please, don't even think about playing with this metadata.


[1] It often does that anyway to satisfy alignment requirements and because of allocator internals (most allocators manage memory in different "buckets" of fixed size), so if you allocate, say, 4 bytes, you nominally get 4 bytes, but the runtime really allocated 8 or 16 bytes most of the time (without you knowing).


You can only free() pointers that were actually malloced (or calloced, realloced). If you try to free only a portion of memory by passing in a different pointer (even one that is "part" of another pointer), the C runtime will not be pleased (as you can see.)


I think you cannot free the memory because free doesn't know how much memory to free.Your program has information about the address malloc() returned and not for every address in this space.So you can free(s1) but not free(s1+3).Also you can handle your pointers as an array in this example: s1[0]='a';


You can only free() memory that was previously malloced, calloced, or realloced, as dlev and Daniel have said.

The reason for this is implementation-dependent, but involves the method of keeping track of allocated memory.

Efficient memory allocation is a difficult problem because different memory allocation algorithms work well depending upon how memory is allocated: a few small chunks, half of which are freed, then slightly larger blocks being grabbed, etc.

The objective is to keep the size of the memory block used by the program at a minimum (usually this chunk will be a continuous block of virtual memory), while keeping the usage of the space within that block extremely high (few gaps between used segments of memory).

Remember that these blocks can't be moved except when being realloced, so there's always going to be some wasted space.

To minimize the waste, metadata about (at least) the size of the block is stored just before it. The memory allocator can look through the used blocks when determining how to handle a new request. If you pick a random memory location, whether part of a previously-allocated region or no, this metadata will not be present and free will be unable to determine what should be freed.


You cannot free that pointer the way you are doing, check this question and its answer: Memory Clobbering Error

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜