Pointer and their use

Thread Starter

anukalp

Joined Jul 28, 2018
158
I have been followed many tutorials to understand the pointer and memory allocation. The explanation given in the book is difficult to understand

Pointer is used to store the address of another variable

Memory allocation has types;
  • Static Memory Allocation: The program is allocated memory at compile time.
  • Dynamic Memory Allocation: The programs are allocated with memory at run time.
When we declare variable, compiler allocate memory space to store the variable content.
Code:
main ()
{
      int variable = 1;
}
for example if I declare int variable it means compiler will allocate memory space to store the value of integer variable.
Let's suppose the memory allocate by compiler is 0001 and the value of variable is 1. it means variable value 1 stored at memory 0001 at compile time

it's little bit difficult for me to understand memory allocation for pointer. I want to understand what this is relation between pointer and dynamic memory allocation. It will be very much appreciated if someone give advice on Pointer and dynamic memory allocation.
 

jpanhalt

Joined Jan 18, 2008
11,087
Hope this helps,but I don't do C, just Assembly (MPASM).

Assume you have a pointer to a block of memory, say 64 bytes, and use that pointer in a FIFO/ring buffer. The pointer is incremented or decremented as the buffer is used. Now assume the buffer is for received data (e.g., sensor readings, ASCII characters). The content at each reserved memory location changes during run time.
 

MrChips

Joined Oct 2, 2009
34,812
You are asking two separate questions, memory allocation, and use of pointers.

Let's talk about memory allocation first.

It depends on if you are writing code in ASM, C, and if you are using an operating system or not.
Memory locations are not assigned at compile time. They are assigned at link time. There is a subtle difference. Static locations are assigned if you declare the variable as global by declaring it outside of any function. It is also static if you use the static keyword in the declaration.
Code:
int this_is_global;
void main(void)
{
  static int this_is_static;
  int this_is_local;
}
If you are developing for small embedded systems, you might have control on the physical location of static global variables. Local variables, declared within the body of a function, are allocated at run time from the application stack.

If you are running under an operating system, you have no control on where your variables, global or local, are allocated. All variables will be allocated from the application heap. Thus, when the application terminates, all storage allocation is recovered.

memalloc( ) is an operating system library function for allocating large blocks of memory during run time. This is dynamic memory allocation.

We will discuss pointers as a separate issue.
 

Thread Starter

anukalp

Joined Jul 28, 2018
158
You are asking two separate questions, memory allocation, and use of pointers.

Let's talk about memory allocation first.
Sure I'lI be focused on memory allocation first . I understand difference between local and global variable
Global variable
Code:
#include <stdio.h>

//global variable
int i;

int main(void)
{
    for ( i = 0; i < 5; i++ );
    {
        printf ("Value : %d", i);
    }
    return 0;
}
Local Variable
Code:
#include <stdio.h>

int main(void)
{
    //Local variable
    int i;
   
    for ( i = 0; i < 5; i++ );
    {
        printf ("Value : %d", i);
    }
    return 0;
}
It depends on if you are writing code in ASM, C, and if you are using an operating system or not.
I run c program's on 64 bit machine using windows 10 operating system

When we declare pointer How does memory allocate for pointer
 

Thread Starter

anukalp

Joined Jul 28, 2018
158
memalloc( ) is an operating system library function for allocating large blocks of memory during run time. This is dynamic memory allocation
I want to understand the explanation given in this wikki page https://en.wikipedia.org/wiki/C_dynamic_memory_allocation

However, the size of the array is fixed at compile time. If one wishes to allocate a similar array dynamically, the following code can be used:

Code:
int * array = malloc(10 * sizeof(int));
What's advantage of above line in program

And when it is necessary to allocate dynamic memory in program
 

MrChips

Joined Oct 2, 2009
34,812
The size of an array may be fixed by the programmer.
sizeof( ) is a library function and will return a result at run time.
A pointer is just another variable that gets store in memory, same as any local, global, or static variable.
 

WBahn

Joined Mar 31, 2012
32,840
I want to understand the explanation given in this wikki page https://en.wikipedia.org/wiki/C_dynamic_memory_allocation

However, the size of the array is fixed at compile time. If one wishes to allocate a similar array dynamically, the following code can be used:

Code:
int * array = malloc(10 * sizeof(int));
What's advantage of above line in program

And when it is necessary to allocate dynamic memory in program
When you don't know how much memory you will actually need (or when you want to store the data on the heap instead of the stack), you allocate the memory dynamically.

So let's first allocated an automatic variable within our main() called intPtr that will be a pointer to an array of integers, but we don't know how many. Then we will ask the user for how many integers the array must be able to hold.

Let's say that the user entered 500 and we stored that value in the variable 'count'. We now need to get the system to reserve a block of memory that is large enough for us to store 500 variables of type int. We use malloc() to do that, but malloc() requires that we tell it how many bytes of memory we are requesting. So we need to multiply the number of int values by the size of a single int variable -- that's where the sizeof() operator comes into play. It returns the number of bytes needed to store a particular data type. On a 64-bit machine it will probably return 8, while on a 32-bit machine it will return 4.

Code:
int main(void)
{
   int *intPtr = NULL;
   int count;

   // Code to get number integers from user and store in variable 'count'

   intPtr = (int *) malloc(count * sizeof(int));
   ...
}
 

WBahn

Joined Mar 31, 2012
32,840
The size of an array may be fixed by the programmer.
sizeof( ) is a library function and will return a result at run time.
A pointer is just another variable that gets store in memory, same as any local, global, or static variable.
The sizeof is NOT a library function and it does nothing at run time. It is an operator defined by the language and it is evaluated at compile time. It must be resolvable to an integer constant at compile time -- though they had to jump through some hoops to get consistent behavior with variable-length arrays in C99.
 

MrChips

Joined Oct 2, 2009
34,812
The sizeof is NOT a library function and it does nothing at run time. It is an operator defined by the language and it is evaluated at compile time. It must be resolvable to an integer constant at compile time -- though they had to jump through some hoops to get consistent behavior with variable-length arrays in C99.
Does sizeof( ) return the size of the data type or does it return the number of elements in an array?
I'm asking because I don't know and too lazy to check it.
 

WBahn

Joined Mar 31, 2012
32,840
Does sizeof( ) return the size of the data type or does it return the number of elements in an array?
I'm asking because I don't know and too lazy to check it.
sizeof ALWAYS returns the number of bytes needed to store the indicated item. Just remember that it always returns a number that has a unit of bytes.
 

xox

Joined Sep 8, 2017
936
Does sizeof( ) return the size of the data type or does it return the number of elements in an array?
I'm asking because I don't know and too lazy to check it.
Depends on scope of the symbol:

Code:
#include <stdio.h>

void process(char data[])
{
    printf("Size from 'process': %zu\n", sizeof(data));    // Prints sizeof(char*) [usually 4 or 8]
}

int main(void)
{
    char buffer[1024];
    printf("Size from 'main': %zu\n", sizeof(buffer));    // Prints 1024   
    process(buffer);
}
 

xox

Joined Sep 8, 2017
936
When we declare pointer How does memory allocate for pointer
When you declare a pointer all you're really doing is allocating a special kind of integer on the stack. More specifically a special kind of unsigned integer capable of storing the maximum possible memory address. In other words a pointer on a 64-bit machine can access any address up to 0xFFFFFFFFFFFFFFFF. So when you declare a pointer on such a machine the compiler just sets aside 8 bytes (64 bits) of memory on the stack. (Never on the heap).

And whenever you use a function like malloc() all that's basically happening is the operating system locates an unused block of memory and then returns a pointer to it. (Again, which is just a memory address). Obviously you need to keep track of it so that you can eventually free() it up at some point. (Otherwise you get a memory leak).

Also, pointers have an actual unsigned integer counterpart (since you have to be able to know the size of some span of memory) and that integer type is called size_t. On a 64-bit system, the maximum number it can hold is of course 0xFFFFFFFFFFFFFFFF. So pointers and size_t go hand in hand. (Meaning you should NEVER use a plain old int in place of size_t when storing the length or size of a variable).

Here's a little code to help demonstrate:

Code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    double* p1 = NULL, * p2 = NULL;
    printf("sizeof(double*): %zu\n", sizeof(double*));
    size_t len = 16;
    p1 = malloc(len * sizeof(double));
    printf("sizeof(p1): %zu\n", sizeof(p1));    // In other words, sizeof(p1) == sizeof(double*)
    printf("address stored in p1 [after malloc]: %p\n", p1);
    printf("address stored in p2 [before assigment]: %p\n", p2);    // NULL
    p2 = p1;
    printf("address stored in p2 [after assigment]: %p\n", p2);    // Whatever malloc returned
    free(p1);
    printf("address stored in p1 [after free]: %p\n", p1);    // Still contains whatever malloc returned
    p1 = p2 = NULL;    // IMPORTANT: always do this after you free() memory to avoid "dangling pointers"
}
From the above it should be clear that assigning a pointer to a memory address DOES NOT affect the actual chunk of memory. You're really just storing/copying integers.
 
Last edited:

Thread Starter

anukalp

Joined Jul 28, 2018
158
Thanks to all of you to provide sufficient information to understand memory allocation. I appreciate work of all the members

There are two types of memory available: stack-based and heap-based memory.

Stack is used for static memory allocation or Stack is used to store local variable. We can use the stack if we know exactly how much data you need to allocate and

Heap is used for dynamic memory allocation. When we use malloc ,calloc, realloc then memory is allocated from heap. We can use heap if we don't know exactly how much data we will need
 

WBahn

Joined Mar 31, 2012
32,840
Depends on scope of the symbol:

Code:
#include <stdio.h>

void process(char data[])
{
    printf("Size from 'process': %zu\n", sizeof(data));    // Prints sizeof(char*) [usually 4 or 8]
}

int main(void)
{
    char buffer[1024];
    printf("Size from 'main': %zu\n", sizeof(buffer));    // Prints 1024  
    process(buffer);
}
But that last one is NOT printing 1024 because that is the number of elements in the array (what was asked). It is printing 1024 because that is the size of the block, in bytes, associated with the array of the array variable 'buffer'. If you made buffer[] to be of type int, then it would have returned (likely) either 4096 or 8192. The sizeof operator ALWAYS returns a size in bytes.
 

WBahn

Joined Mar 31, 2012
32,840
Thanks to all of you to provide sufficient information to understand memory allocation. I appreciate work of all the members

There are two types of memory available: stack-based and heap-based memory.

Stack is used for static memory allocation or Stack is used to store local variable. We can use the stack if we know exactly how much data you need to allocate and

Heap is used for dynamic memory allocation. When we use malloc ,calloc, realloc then memory is allocated from heap. We can use heap if we don't know exactly how much data we will need
There's more to it than this. Static memory is memory that is allocated for the duration of the program and it almost always (I'd have to look to see if there are any exceptions) is allocated off the heap. You do NOT want this memory on the stack because memory on the stack is automatically allocated and deallocated as functions are called and return. This type of memory is called "automatic" memory and local variables and function parameters are automatic.
 

xox

Joined Sep 8, 2017
936
But that last one is NOT printing 1024 because that is the number of elements in the array (what was asked). It is printing 1024 because that is the size of the block, in bytes, associated with the array of the array variable 'buffer'. If you made buffer[] to be of type int, then it would have returned (likely) either 4096 or 8192. The sizeof operator ALWAYS returns a size in bytes.
Sorry, yeah I overlooked that bit of the question. Thanks. :)

Static memory is memory that is allocated for the duration of the program and it almost always (I'd have to look to see if there are any exceptions) is allocated off the heap.
I would think neither the stack or heap, but in any case the important point like you say is that they exist throughout the duration of execution.
 

WBahn

Joined Mar 31, 2012
32,840
I would think neither the stack or heap, but in any case the important point like you say is that they exist throughout the duration of execution.
This probably comes down to implementation details. Most languages, including C, do not even specify whether the implementation is stack-oriented or not. For instance, in the C99 draft standard (N869) that I keep as a reference neither the word stack nor heap appear anywhere in the 566 page document. So only required behavior is defined and the implementer is free to play whatever games they want to get that behavior. None-the-less, most implementations use the same techniques for the basics. I think some of the simpler compilers only have the notion of "stack" and "heap" and basically pre-allocate global and static data from the heap, adding runtime code to initialize it as needed. Other memory models are more sophisticated and have an initialized data segment, an uninitialized data segment, a stack, and a heap with the heap only be used for run-time dynamically-allocated memory. I would imagine there are several other variants, as well.
 

MrSoftware

Joined Oct 29, 2013
2,273
Typically an application has only so much stack space. When a function call is made, a bunch of things are pushed to the stack to be saved for later (after the function returns), and some of the stack space is used by the function that was called. Total stack space available to your application is often configurable, though the method will change depending on your compiler and the platform (operating system) that you're running on. Here are a couple of articles that explain stack usage better than I can:

https://manybutfinite.com/post/journey-to-the-stack/
https://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64

Here is a Microsoft example uses recursion to purposefully overflow the stack, catch the exception and return. This will give you a rough idea of your stack space with your current compiler settings, and it shows you how to catch a stack overflow and potentially recover, hopefully saving your process from crashing. You can try changing your available stack space, then run this to see if the change worked:

https://msdn.microsoft.com/en-us/library/89f73td2.aspx
 
Top