EFiore
EFiore

Reputation: 115

function returns a pointer

I am rather new to C and I am having a hard time getting a hang of all these pointers. In other words the dereferencing operator and the ampersand operator. I believe, after staring at them for a while I am starting to understand how they work. For example:

    int x = 1;            //this creates an integer variable called x and assigns one to it
    int *pointer;     //this creates a pointer variable that will point to an integer
    pointer = &x;     //now the variable pointer points to x
    *pointer = 0      //the value that pointer points to is now zero

I'm pretty sure I understand how that works.
I am reading through "The C Programming Language" by Kernighan and Ritchie but I am confused by their some code they have in section 5.4 (address arithmetic). I should point out that I understand address arithmetic so my question does not pertain to that. Nor is my question about the code inside the below function does. Searching online for questions about this code generates a lot of posts where people do not understand how the code in the if/else statement operates. In any case, my question is specifically about the function name itself.

    #define ALLOCSIZE 1000
    static char allocbuf[ALLOCSIZE];
    static char *allocp = allocbuf;

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

Again, I understand the code in the function but how does

*alloc

work? I understand this function returns a pointer. Does this imply that by having the function name be a pointer we are returning a pointer to a char type? If so, what does it point to? In my earlier example, we have

    int x = 1;
    int *pointer;
    pointer  = &x;

Here the variable "pointer" is pointing to the x variable. However. in the function alloc doesn't point to anything. Any help would be appreciated.

Upvotes: 3

Views: 834

Answers (3)

Ryan
Ryan

Reputation: 180

This function

char *alloc(int n)  /*return pointer to n charachters*/

will return a pointer to a character

It may be easier to to understand if it is written this way:

char* alloc(int n)  //subtle, but this change in format can help

Now, as to what the pointer actually points to. Previously, on this line;

#define ALLOCSIZE 1000
static char allocbuf[ALLOCSIZE];

a char array of size 1000 is created. We have an array of 1,000 chars, and the name ‘allocbuf’ points to the first element in the array. Next, on this line;

static char *allocp = allocbuf;

We create a pointer (allocp) to the first element of the 1,000 char array (allocbuf). Both the array and the pointer are global variables. They can be accessed anywhere in the program. In the example you posted, these variables will be used in the alloc function.

Before we proceed, it would make sense to define what the purpose of the function is. The purpose is to use the previously defined 1000 char array (it may help you to think of a char as a single byte) to allocate memory. So the function will keep track of what memory has been used. And return a pointer to a block of size ‘n’ that can be used (or null ‘0’ if there isn’t enough memory).

Don’t be concerned with how memory is freed in this example. I reread the section that you pulled this example from, and it later defines a method called ‘afree’ to free the memory allocated by this function.

The function keeps track of the memory that has been used by incrementing ‘allocp’ (the pointer to the array of 1000 chars) by ‘n’ (the size requested) every time memory is requested. Then, when the user of the function requests more memory, it checks to make sure that request can be fulfilled by these lines;

if (allocbuf + ALLOCSIZE – allocp >= n)
    …
else{
    return 0;
}

if the requested size doesn’t fit, null is returned. The function makes use of the current position of ‘allocp’ to determine if there is enough memory remaining from previous calls. If the size requested does fit, then this happens;

allocp += n;
return allocp – n;

What this does is increment ‘allocp’ by however much memory was requested. This pointer is used to keep track of how much memory has been requested of this function. Since the function can fulfill the memory request, it now considers the requested memory to be in use. Thus, the pointer is now pointing toward the first char in the 1000 char array that is not in use. Then, after incrementing the pointer, the function returns a pointer to the first char of the block of memory requested by subtracting ‘n’ (the size requested) from the current position of ‘allocp’.

Throughout all of this, nobody has any idea what the value of this memory actually is. No one has any clue what allocbuf[13] or allocbuf[314] contains. This function only manages what memory is free and what is taken, it doesn’t care what is actually stored in the memory.

If a user asks for 4 bytes like so

char* 4bytes = alloc(4)

stores a 32-bit int in it like so;

//don’t ever actually do this!!!
int* 4bytesInt = (int*)4bytes;
*4bytesInt = 2,147,483,647;

then the first four elements of allocbuf contain that integer. If you free the memory;

afree(4bytes);

then the pointers still work and the first 4 elements of allocbuf contain that integer still. Nothing has actually changed the value of these bytes. If you request memory again, however

char* 4bytesAgain = alloc(4);

Then alloc will return THE SAME 4 BYTES TO ‘4bytesAgain’ THAT IT RETURNED TO ‘4bytes’! Since the memory was freed, the ‘alloc’ function feels free to reuse it. So if you now fill these four bytes with, say, a name;

4bytesAgain[0] = ‘C’;
4bytesAgain[1] = ‘A’;   
4bytesAgain[2] = ‘R’;
4bytesAgain[3] = ‘L’;

then this will change the values pointed to by the original ‘4bytes’ and ‘4bytesInt’.

Upvotes: 2

atru
atru

Reputation: 4744

char *alloc(int n) means that alloc is a function that returns a pointer to char. In this case it is a pointer to the first element of an array that represents the memory block booked by alloc. Putting * next to alloc may be a little misleading, think of it more as char* alloc(int n).

The function name is not a pointer, what it returns is - just like you would write int fun(int x) - except that here return value is not int but char *.

Upvotes: 0

ImaginaryHuman072889
ImaginaryHuman072889

Reputation: 5205

It just means that whenever the function is called, it will return a pointer to a char.

For example, when this function is called you might see something like this:

char* x;
x = alloc(5);

Upvotes: 0

Related Questions