Quabs
Quabs

Reputation: 51

Size of pointers and dynamic arrays

I'm relatively new to C, and I've been messing around with pointers to an int array to help solidify my understanding. Here is some code I typed up that confused me:

#include <stdio.h>

int main(int argc, char **argv)
{
    int sizeOfInt = sizeof (int);
    printf("The size of an int is %d \n",sizeOfInt);

    int StaticArray[10];
    int staticSize = sizeof(StaticArray);
    printf("The size of the static array with 10 elements, all unused, is %d\n\n", staticSize);


    int *DynamicArray = malloc( 10  * sizeof(int) );
    printf("The dynamic array *DynamicArray has been allocated 10 int elements worth of memory\n");
    int sizeOfDynamic = sizeof(DynamicArray);
    printf("Since none of those elements have been assigned an int yet, the array currently takes up %d memory\n\n", sizeOfDynamic);

    *DynamicArray = 10;
    printf("The first element, at address %x , is %d \n",DynamicArray, *DynamicArray); //DynamicArray refers to address of start of array
    printf("The address of the pointer *DynamicArray is %x \n",&DynamicArray); //&DynamicArray refers to address of pointer

    DynamicArray[1] = 20;
    printf("The second element, at address %x , is %d \n",DynamicArray, DynamicArray[1]); //DynamicArray refers to address of start of array

    sizeOfDynamic = sizeof(DynamicArray);
    printf("The size of the array after assigning 2 int elements is now %d", sizeOfDynamic);

    //Free unused memory
    free(DynamicArray);
    return 0;
}

When I run this program, I get the following output:

The size of an int is 4
The size of the static array with 10 elements, all unused, is 40

The dynamic array *DynamicArray has been allocated 10 int elements worth of memory

Since none of those elements have been assigned an int yet, the array currently takes up 8 memory

The first element, at address 1f69b0 , is 10

The address of the pointer *DynamicArray is 62fe08
The second element, at address 1f69b0 , is 20

The size of the array after assigning 2 int elements is now 8
  1. Why is it that before assigning any elements to *DynamicArray, its size is 8?

  2. Since *DynamicArray had a size of 8 to begin with, how does it still only have a size of 8 after assigning two elements to it?

  3. If I allocated 10 int elements worth of memory for *DynamicArray, it is initially as wasteful of memory as a static array of 10 elements until I call free(DynamicArray), correct?

Thank you for any clarification!

Upvotes: 2

Views: 1505

Answers (3)

bhushan23
bhushan23

Reputation: 501

Why is it that before assigning any elements to *DynamicArray, its size is 8?

And

Since *DynamicArray had a size of 8 to begin with, how does it still only have a size of 8 after assigning two elements to it?

You are doing sizeof(DynamicArray) which will return size of integer pointer and you are running this program on 64-bit machine where pointer will of of 8 bytes. Try following

  1. Run above program on 32-bit machine (32-bit OS)

  2. Run above program under MS-DOS / Turbo C++ (16-bit environment)

size is 4 and 2 bytes respectively.

Pointer size is depended on the environment you are running your program in.

If I allocated 10 int elements worth of memory for *DynamicArray, it is initially as wasteful of memory as a static array of 10 elements until I call free(DynamicArray), correct?

Yes and No. All the dynamic allocation is done on heap space and managed by different routine than than of stack space. So technically, it is as wasteful as array of ten elements. But recommended if you really are going to use 10 elements of space than doing in chunk - lets say allocate 5 first and then reallocate extra 5.

Upvotes: 0

DWR
DWR

Reputation: 898

I was right where you a few months ago.

  1. DynamicArray itself is just a "container" (roll with it...) for a memory address, which has a certain size dependent upon platform. It points to a memory address, and whatever values reside at that memory address do not change the size of its address. If you put a fat person in a house, it does not change the houses address.

  2. Same answer as 1?

  3. "Wasteful" maybe not the right phrase, but it takes up the same amount of memory. Difference is the one allocated with malloc(...) is on the heap, and outlives the scope of the function it was called in, until explicitly free()'d.


sizeof(DynamicArray[i]) = sizeof(int), whether assigned a value or not (assuming i is within bound). sizeof(DynamicArray) = sizeof(int*)

You are compiling to 64-bit it seems. Change to 32-bit and watch sizeof DynamicArray get cut in half. That might help you visualize?

Upvotes: 1

Govind Parmar
Govind Parmar

Reputation: 21542

Pointers and arrays are not the same thing in C. If you use a function like malloc to dynamically allocate an array to a pointer variable, it is your job as the programmer to ensure that assignment to the array you allocated does not exceed its boundaries.

Technically, this is also the case with stack-allocated arrays of fixed length, but sizeof will return the actual number of bytes that were allocated in that case.

What you've stumbled upon is actually one of the reasons that strings in C need to be null-terminated - a string of type char * does not have any information about its length, so the only way for library functions to know when they're done processing a string is by searching for a null terminator. For example, the library function strcat, which appends two strings, is usually implemented like so:

void strcat(char *dest, char *src)
{
     while(*dest != '\0') *dest++;
     while(*src != '\0') *dest++ = *src++;
}

The check for the null is required because there is no information about how long the string actually is in either dest or src - if you were to try to determine the length of dest using sizeof it would fail because you'd get the size of a pointer on your architecture.

Upvotes: 0

Related Questions