Home > Back-end >  C array dynamic memory has no upper limit
C array dynamic memory has no upper limit

Time:07-12

I have my code here:

int main(){
  printf("%lu\n",(1 * sizeof(int)));
  int* hello=malloc(1 * sizeof(int));
  hello[1000000]=10;
  printf("%d \n",hello[1000000]);
  printf("%lu \n", sizeof(hello));

  int* goodbye=malloc(100 * sizeof(int));
  printf("%lu \n",sizeof(goodbye));

  hello=goodbye;

  printf("%lu \n",sizeof(hello));

  hello=realloc(hello,20);

  hello[1]=0;

  printf("%lu \n",sizeof(hello));
}

It outputs this:

4 10 8 8 8 8

This throws has no warnings or errors, which is strange to me because I allocate only 4 bytes for the array hello, but can access hello[1000000].

Also, I tried to resize hello with goodbye, but the size stays the same. At line 10, I do hello=goodbye; which should resize it? I'm a little new to c memory stuff. Realloc also does not change the size of my array. I am trying to make "hello" be a dynamically sized array. What am I doing wrong here?

The code is supposed to be barebones reallocating memory and changing the size of an int array.

CodePudding user response:

This throws has no warnings or errors, which is strange to me because I allocate only 4 bytes for the array hello, but can access hello[1000000].

This is undefined behaviour. You got (un)lucky and it happened to work for you this time. This is not guaranteed however, and you should never rely on this kind of behaviour.

Also, I tried to resize hello with goodbye, but the size stays the same.

The 8 you're seeing is the size of a pointer, not the size of the thing it is pointing to. No matter how much memory you allocate, a pointer to that memory will always be the same size.

At line 10, I do hello=goodbye; which should resize it? I'm a little new to c memory stuff.

This is not resizing it, this is just making hello point to the same location as goodbye.

A drawing might help.

Before, you have this:

hello             goodbye
|                    |
|                    |
|                    |
v                    v
MEMORY 1          MEMORY 2

After doing hello = goodbye, you have this:

hello             goodbye
|                     |
\-----------------\   |
                  |   |
                  v   v
MEMORY 1         MEMORY 2

i.e., hello now points to the same spot as goodbye.

Realloc also does not change the size of my array. I am trying to make "hello" be a dynamically sized array. What am I doing wrong here?

Realloc does change the size of the array, you're not not looking at the size of the array, you're looking at the size of a pointer, as mentioned above.

CodePudding user response:

This throws has no warnings or errors, which is strange to me because I allocate only 4 bytes for the array hello, but can access hello[1000000].

You're in a territory known as "undefined behavior". C does not guarantee that your program will crash in such a scenario. It could be that hello[1000000] happens to fall on an address that's valid for other reasons. In doing so, it could corrupt memory that has some other important purpose.

On my machine, it crashed. On https://godbolt.org/ (a tool that's used to investigate programs and compilers), it also crashed.

Also, I tried to resize hello with goodbye, but the size stays the same. At line 10, I do hello=goodbye; which should resize it?

You didn't resize it. You still have a memory allocation of size 1 * sizeof(int)). hello used to point to it, but now it no longer does, but it's still there in memory, taking up space. You created a new allocation of size 100 * sizeof(int) and made hello point to that instead.

Realloc also does not change the size of my array. I am trying to make "hello" be a dynamically sized array. What am I doing wrong here?

As long as you properly keep track of the size and properly realloc, you're on the right path to making a variable sized array. In particular, as long as realloc(hello,20); succeeds, you now have memory to safely store 20 bytes worth of data (i.e. five 4-byte ints).

You may want to consider defining a struct, which can hold two items: a pointer to the buffer you allocated, and a size_t indicating its current size. When you need a bigger array, realloc and update the size.

The problem that you're seeing comes from sizeof(hello) - that doesn't actually check the size of the array, but simply indicates the size of the pointer itself. On my machine, the size of a pointer is eight bytes, so it always prints 8.

  • Related