0

I am new to dealing with pointers and memory allocation. I don't understand what am I doing wrong. This is my code:

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

int main() {
     int* i;
     printf("Size of i:%d\n",sizeof(i));
     i = malloc(5 * sizeof(int));
     printf("Size of i:%d\n",sizeof(i));
     i[100] = 3;
     printf("Impossible i:%d\n",i[100]);
}

I compile it using gcc file.c. From my understanding, this should not have been compiled since i[100] is not allocated. Instead I get an output:

Size of i:8
Size of i:8
Impossible i:3

What am I missing here? Disregarding the impossible i, to my understanding the output of the first two lines should have been

Size of i:8
Size of i:40
Roberto Caboni
  • 6,078
  • 10
  • 19
  • 34
Joshhh
  • 355
  • 1
  • 2
  • 14
  • 3
    `sizeof` won't give you the size of the allocated memory pointed by a pointer but the size of the pointer itself which is constant and which is normally 4 or a 32 bit platform and 8 on a 64 bit platform. – Jabberwocky Apr 21 '20 at 07:52
  • @Jabberwocky I see, so how can you get the size of an array? – Joshhh Apr 21 '20 at 07:53
  • 1
    If you have `int array[some_size]`, `sizeof (array)` is the total size of the array in bytes. If you have `int *array = malloc(some_size)` you cannot get the size of the memory pointed to by `array`. – Jabberwocky Apr 21 '20 at 07:54
  • 1
    You're confusing "not compile" with "not run correctly". C doesn't detect all of your runtime errors. If it could, it would be able to solve the halting problem, which is easily shown to be impossible. Unlike most interpreted languages, C doesn't have the training wheels you're used to. Instead, you have to agree not to violate any number of rules, and in return it guarantees to run correctly. If you violate any of those rules, then all bets are off. You violated a rule (you wrote past the end of a dynamically allocated array). All bets are off. – Tom Karzes Apr 21 '20 at 07:58
  • And `sizeof(pointer)` is constant for a given pointer type. It is not the same as `sizeof(array)`. In fact, `sizeof(i)` is well defined even before you assign anything to `i`. It's the same as `sizeof(int *)`. If you want the size of a dynamically allocated array, you have to remember how you allocated it. Save the size in a variable. – Tom Karzes Apr 21 '20 at 08:05
  • Writing a fantastic answer and discovering you can't post it because the question has been closed in the meantime... priceless! :) – Roberto Caboni Apr 21 '20 at 08:13

1 Answers1

2

From my understanding, this should not have been compiled since i[100] is not allocated.

It' simply undefined behaviour to access out of bounds. For undefined behaviours, compilers may or may not issue diagnostics. There's no requirement from the language.

Disregarding the impossible i, to my understanding the output of the first two lines should have been

Size of i:8
Size of i:40

The sizeof operator on a pointer, unlike arrays, can't deduce the size of the memory block it's point to. It's always going to give the size of the pointer i.e. sizeof(i) == sizeof (int*).

There's no way to deduce it from the pointer; you just have to keep track of it yourself. One way is to store the value 5 in a variable and if malloc succeeds, you know there's space for 5 int's.

P.P
  • 106,931
  • 18
  • 154
  • 210