2

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!

6
  • 1
    "Here is some code I typed up that confused me:" --> It is surprising someone who can write this code would have these questions. Commented Jun 17, 2017 at 16:09
  • Solution: pointer are not array. Commented Jun 17, 2017 at 16:10
  • 1
    "how does it (DynamicArray) still only have a size of 8" DynamicArray is a pointer. Its size does not change. Commented Jun 17, 2017 at 16:10
  • 3
    Note that sizeof(DynamicArray); tells you nothing about the memory you allocated. It is the size of the pointer, whether or not it is initialised. Commented Jun 17, 2017 at 16:10
  • 1
    Possible duplicate of How to find the 'sizeof' (a pointer pointing to an array)? Commented Jun 17, 2017 at 16:14

3 Answers 3

1

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?

Sign up to request clarification or add additional context in comments.

4 Comments

"sizeof(DynamicArray[i]) = sizeof(int), whether assigned a value or not (assuming i is within bound). " Thanks, this also provides some clarification. But then, since sizeof(DynamicArray[i]) is the same regardless of whether there's anything assigned to it, what is the advantage of a Dynamic Array? Is the only advantage the fact that I can call free(DynamicArray) to get that memory back throughout the rest of the program?
@Quabs The main advantage of malloc and free is that the lifetime of the array is not limited to where the array was declared. You can pass the pointer out of the function, etc.
Allocated on stack, versus allocated on heap. That is outside the scope of the original question but you are in for a fun ride!
@aschepler & David Rogers Ahh I see, thank you! I'm so unfamiliar with memory management in C still that I'm always forgetting stuff like this.
0

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.

9 Comments

thank you, this answer cleared things up for me some I believe. So when I called sizeof(DynamicArray) twice throughout that program, it was just returning the size of the actual pointer itself both times, and had nothing to do with the size of the actual contents of that array, correct? Also, since only character arrays are null-terminated, when using an int array I need to keep track of how much space I have manually, correct? (ie there's no way to "null terminate" an array of ints)
"so the only way", what this should be the only way ?
@Stargateur I'm not sure what you're asking me
@GovindParmar "library functions", could take the size as argument.
@Quabs Actually, you can null terminate an array of ints, if you prefer. This may be less efficient than also passing an explicit size, since other code would need to search for the end. And it requires some "sentinel" value like 0, -1, or MIN_INT which you know can't be in the actual data.
|
0

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.

2 Comments

FWIW, the heap allocated memory will likely contain a heap management header and trailer before and after the allocated memory which the stack allocated memory will not.
Right. and heap allocation is more complex and also costly in terms of time

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.