-1

Code:

typedef long Align;
union header {
        struct {
                union header *ptr;
                unsigned size;
        } s;
        Align x;
};

typedef union header Header;

................
................
................

static Header *morecore(unsigned nu)
{
        char *cp, *sbrk(int);
        Header *up;
        if (nu < NALLOC)
                nu = NALLOC;
        cp = sbrk(nu * sizeof(Header));
        if (cp == (char *) -1)
                return NULL;
        up = (Header *) cp;
        up->s.size = nu;
        free((void *)(up+1));
        return freep;
}

Doubt:

Consider the morecore function is calling from some other function and receive 4 as int from argument(nu). I am having doubt in the following statements.

cp = sbrk(nu * sizeof(Header));
if (cp == (char *) -1)
        return NULL;
up = (Header *) cp;
up->s.size = nu;

up is just a pointer to Header. But, still it does not point to any Header variable. sbrk allocates requested memory and returns current program break and it is stored in cp. Then the address stored in cp is casted and assigned to up. Now, the up contains the address which is returned by sbrk as a pointer to Header variable. Then the following statement occurs,

up->s.size = nu;

up contains only the address returned by sbrk. Then how the above statement store the nu in the size variable.

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
mohangraj
  • 9,842
  • 19
  • 59
  • 94
  • This is on a 32-bit OS with 4-bit pointers? – David C. Rankin Jul 09 '15 at 05:02
  • Yes. "Linux ltsp63 3.2.0-33-generic #52-Ubuntu SMP Thu Oct 18 16:19:45 UTC 2012 i686 i686 i386 GNU/Linux" – mohangraj Jul 09 '15 at 05:04
  • So `sbrk` pushes the data segment, you get the address last break of program and the gap is `nu * sizeof(Header)`. You are casting this to type `Header` dereferencing it for writing. Now what is the question? Something like this is used by many `*alloc` implementations. – Mohit Jain Jul 09 '15 at 05:08
  • @mohanraj You understand that a cast to `Header *` does nothing to change the information stored at `cp` and serves only to allow assignment of the pointer returned by `sbrk` to `up`? – David C. Rankin Jul 09 '15 at 05:13
  • All variables are just some memory location. The casting allows you to interpret the memory pointed to as any type you like. In effect you are telling the compiler: "Here is some memory and I know it points to a variable of this type. Make it so". This is one of the powers and one of the dangers of C. – kaylum Jul 09 '15 at 05:13
  • Here, up is the pointer which contains only the address of type header. But, here we didn't allocate any block of memory using malloc to the pointer variable up. Then how, it will be right to store the nu into size. – mohangraj Jul 09 '15 at 05:16
  • @Alan Au So, you say like "int\* ptr;" is equal to "int \*ptr=(int\*)malloc(sizeof(int));" – mohangraj Jul 09 '15 at 05:21
  • `sbrk` does allocate memory. `up` points to that allocated memory. `malloc` is not the only way to get allocated memory (e.g. In addition to `sbrk` there are `mmap` and `alloca`). – kaylum Jul 09 '15 at 05:23
  • What is freep ? NALLOC ? Why use function name to instantiate char * variable ? (sbrk(int)) Why use free ? – eroween Jul 09 '15 at 08:32

1 Answers1

0
// sbrk allocate "nu * sizeof(Header)" bytes at the address returned in cp.
cp = sbrk(nu * sizeof(Header));
// if cp is set to error return value (void *)-1 then cp is an invalid address.
if (cp == (char *) -1)
        return NULL;
// up is a pointer and its value is set to the new address (cp).
up = (Header *) cp;
// up is set to the new data allocated by sbrk in the memory. "->" will resolve the address in "up" and store the data.
up->s.size = nu;
eroween
  • 163
  • 11