1

I am running into a problem when i am freeing memory using sbrk. I pass sbrk a negative value but it doesnt decrement the start of the heap. Here is the code

int main(int argc, char** argv) {
    void * a = sbrk(0);
    printf("%p\n",a);

    sbrk(2);
    sbrk(-1);
    a = sbrk(0);
    printf("%p\n",a);
}

And here is sample output:

0x10734f000

0x10734f002

I don't understand why the printed value isn't coming back as 0x10734f001 after sbrk is decremented by one.

I am not allowed to use malloc in this program. This is for a custom implementation of malloc and free using sbrk

cthemc
  • 27
  • 1
  • 7
  • Check the return value of your `sbrk(-1)`... Perhaps you aren't allowed to do that... – twalberg Mar 26 '14 at 16:13
  • the return value is the same as the value for sbrk(0). is there another way to decrement the sbrk value then? – cthemc Mar 26 '14 at 16:17
  • What OS/hardware/etc.? brk is very platform specific. (works as you intend it to on my linux/amd64) – keltar Mar 26 '14 at 16:34
  • @keltar im writing it in netbeans 7 on mac os x and compiling with 32 bit architecture – cthemc Mar 26 '14 at 16:40
  • http://www.opensource.apple.com/source/Libc/Libc-825.40.1/emulated/brk.c I'm not sure it is actual code for i386 (or whatever), but behaviour you're experiencing fits into it quite well. – keltar Mar 26 '14 at 16:48
  • thats so weird. bit of an annoyance :/ – cthemc Mar 26 '14 at 16:56
  • Is it required to use `sbrk`? If not, i'd rather stick to `mmap` as it is just much more predictable and don't suffer fragmentation – keltar Mar 26 '14 at 17:17
  • @keltar yes i believe we have to use sbrk :/ – cthemc Mar 26 '14 at 18:11

5 Answers5

2

It could be that the sizes you use are too small, so that there is some form of rounding happening inside sbrk(). I would never expect byte-level precision for something like this, it's more likely to work in units of pages (which are 4 KB or thereabouts on typical Linux systems).

Also, note that the manual says:

Avoid using brk() and sbrk(): the malloc(3) memory allocation package is the portable and comfortable way of allocating memory.

It's likely that malloc() knows about any limitations sbrk() has and handles them, it's the preferred application-level interface.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • i've seen it in a lot of places. here is one http://stackoverflow.com/questions/2051994/how-do-i-free-memory-obtained-by-sbrk – cthemc Mar 26 '14 at 16:08
  • @cthemc Thanks! I also failed to see the mention of negative increment that the manual page had. I've edited. – unwind Mar 26 '14 at 16:11
  • i have to write my own malloc for a school project. the prompt suggests using a negative parameter so im not sure why what i have is not working >_ – cthemc Mar 26 '14 at 16:14
  • Which platform are you on? Your example works for me (Linux), no matter how large increment/decrement pairs are. Did you notice that `sbrk()` doesn't return the new but the previous `brk`? – mfro Mar 26 '14 at 16:48
  • @mfro im on mac os x compiling with a 32 bit architecture – cthemc Mar 26 '14 at 17:08
  • OS/X and Linux `sbrk()`should do the same thing, according to the manpages. Linux says "`sbrk()` returns the previous program break" while the MaxOSX manpage says "`sbrk()` returns the base of the new storage" which sounds completely different but is essentially the same thing. It may sound weird, but `sbrk(0)` and `sbrk(1000)` actually return the same (correct) value - the previous program break. – mfro Mar 26 '14 at 17:20
2

Just tested it with MacOSX Mavericks and sbrk() behaves (nearly) the same than on Linux with two exceptions:

  • I get a compiler warning: tst21.c:12:6: warning: 'sbrk' is deprecated [-Wdeprecated-declarations]
  • it doesn't seem to be possible to give back memory to the OS using a negative value (this is - as far as I remember - the same behaviour observed on SYSV4 decades ago: releasing memory allocated by sbrk() wasn't possible)
mfro
  • 3,286
  • 1
  • 19
  • 28
0
int main(int argc, char **argv) {
  void *a = sbrk(0);
  printf("%p\n", a);

  a = sbrk(2);
  printf("%p\n", a);

  a = sbrk(-1);
  printf("%p\n", a);

  a = sbrk(0);
  printf("%p\n", a);
}

Output:

0x560267a31000
0x560267a52000
0x560267a52002
0x560267a52001

According to manual void *sbrk(intptr_t increment) return old value of brk when success. sbrk(0) return current brk.

douyu
  • 2,377
  • 2
  • 14
  • 27
-1

printf uses malloc and thereby increases the data segment size

zorgos
  • 1
-1

Try it out without using printf and print out your results by using a debugger. It will work fine and the result will be as expected. The heap will get incremented by 2 and decremented by -1, as intended.

nebadi
  • 1