1

Is there any way I could find how much bytes are allocated for RandomArray in this code

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

    int main()
    {
    int *RandomArray;
    int n;
    srand(time(NULL));

    RandomArray=malloc(sizeof *RandomArray * (rand()%11));
    printf("%d  %d",sizeof(RandomArray),sizeof(*RandomArray));

    return 0;
    }

Also I don't know whether above code will ever have any kind of practical usage. But I am looking from programming perspective.

user2736738
  • 30,591
  • 5
  • 42
  • 56
Tanmay Deshpande
  • 49
  • 1
  • 1
  • 3
  • 1
    nope.. need to keep track of that yourself. – yano Feb 24 '18 at 02:46
  • And you don't save the result of `rand()%11` and validate it is greater than zero, because...? – David C. Rankin Feb 24 '18 at 02:53
  • @DavidC.Rankin well, `malloc(0)` is not illegal. – Pablo Feb 24 '18 at 02:55
  • It's also not very useful... – David C. Rankin Feb 24 '18 at 02:55
  • @ely I looked to close this as a dup, but that Q isn't a direct dup. While you are certainly correct that the explanation there should suffice, that Q is more about the inability to use `sizeof` if an array has decayed to a pointer or you are using a pointer to array. It doesn't directly cover the case where you lack the foresight to save what you allocate. – David C. Rankin Feb 24 '18 at 02:59
  • @DavidC.Rankin not, but the OP is not using the memory anyway, the OP wants to know the size. – Pablo Feb 24 '18 at 03:09
  • 3
    Yes, got that, the whole problem here is if you don't save the size you allocate, there is no magic wand to wave to get it back.... It's one of those "smack yourself in the forehead" type issues. – David C. Rankin Feb 24 '18 at 03:11
  • `sizeof(RandomArray)` is the size of the pointer. It is not the size of the allocation. `sizeof(*RandomArray)` is the size of an `int`. – chux - Reinstate Monica Feb 24 '18 at 03:46

5 Answers5

4

Yes, by saving the size in a variable:

int main()
{
    int *RandomArray;
    int n;
    srand(time(NULL));

    size_t size = rand() % 11;
    if(size == 0)
    {
        fprintf(stderr, "Size 0, no point in allocating memory\n");
        return 1;
    }

    RandomArray = malloc(size * sizeof *RandomArray)
    if(RandomArray == NULL)
    {
        fprintf(stderr, "no memory left\n");
        return 1;
    }
    printf("%zu  %zu\n", sizeof(RandomArray), size);

    // don't forget to free the memory
    free(RandomArray);

    return 0;
}

Note that sizeof(RandomArray) returns you the size that a pointer to int needs to be stored in memory, and sizeof(*RandomArray) returns you the size of an int.

Also don't forget to free the memory.

Pablo
  • 13,271
  • 4
  • 39
  • 59
3

Since the expression *RandomArray is of type int, sizeof(*RandomArray) evaluates to sizeof(int). It does not tell you how much memory was allocated.

When dynamically allocating memory, you need to keep track of how much was allocated yourself. In the case above, you would need to store the random number someplace so you know what that amount is.

dbush
  • 205,898
  • 23
  • 218
  • 273
3

Ah this is experimental code. Interesting things are there.

  • You will allocate memory for N integers where N is between 0 to 10 including 0 and 10.
  • Then you applied sizeof to the pointer (int*) and what it points to (int). It won't matter how much memory you allocate. The output from this line will be same.

  • There is no error check here. if it was you couldn't tell whether it is successful entirely surely because rand() may give 0 as result. You need to store it somewhere and check whether it is 0 because on that case malloc may or may not return NULL.

  • Printing what sizeof returns should be done using %zu format specifier. It returns size_t.

  • To be more clear remember it is a pointer pointing to dynamically allocated memory. RandomArray is not an array - it is an pointer pointing to contiguous memory. That doesn't make it array. It is still a pointer. And the sizeof trick that you wanted to apply thinking RandomArray is an array won't work. In general we keep track of it - using some variable. But here you don't know how much memory you allocated.
  • malloc may return NULL when you pass 0 to it. Handle that case separately. In case you get sz!=0 and get NULL in RandomArray throw error.

      size_t sz = rand()%11;
      RandomArray = malloc(sz);
      if(!RandomArray && sz){
         perror("malloc");
         exit(EXIT_FAILURE);
      }
    

After all this talk - the short answer is, with this setup there is no use of the code (code you have written) so far. You don't know what rand() returned on that case inside malloc.

user2736738
  • 30,591
  • 5
  • 42
  • 56
1

sizeof(RandomArray) always results in 4 bytes(equal to pointer size), if you want to find how many bytes allocated for RandomArray

/* Since its implimentation dependent, so I'm not 
  advising you to access RandomArray[-1], also proper type casting needed */
printf("memory allocated = %d \n",RandomArray[-1]);

From

The C programming language by Denis Ritchie & Kernighan

 typedef long Align;    /* for alignment to long boundary */
   union header {         /* block header */
       struct {
           union header *ptr; /* next block if on free list */
           unsigned size;     /* size of this block */
       } s;
       Align x;           /* force alignment of blocks */
   };
   typedef union header Header;

The Align field is never used;it just forces each header to be aligned on a worst-case boundary. In malloc,the requested size in characters is rounded up to the proper number of header-sized units; the block that will be allocated contains one more unit, for the header itself, and this is the value recorded in the size field of the header. The pointer returned by malloc points at the free space, not at the header itself.

              RandomArray[-1]                      
   -----------------------------------------
   |        |     SIZE     |               |
   -----------------------------------------
                                          RandomArray

        -> a block returned by malloc 
Achal
  • 11,821
  • 2
  • 15
  • 37
  • Is there anything in the standard that guarantees that `malloc` saves the size before pointer is returning? I don't think you can relay on that. – Pablo Feb 24 '18 at 02:53
  • But isn't that just an implementation detail? Do all `malloc` implementation do that as well? – Pablo Feb 24 '18 at 02:57
  • If the requested memory cannot be allocated, a null pointer is returned. If the size of the space requested is zero, the behaviour is implementation-defined: either a null pointer is returned. – Achal Feb 24 '18 at 03:01
  • 3
    While this answer does provide useful information about a common implementation detail, it unfortunately is _an implementation detail_, i.e. absolutely _**not guaranteed to work that way**_. Further, indexing `RandomArray[-1]` is almost guaranteed to fail — you’ll need a much more sophisticated cast than that to do it correctly. – Dúthomhas Feb 24 '18 at 03:09
  • 2
    That is only an example of a storage allocator (from K&R Example 8.7); the Standard does not mandate such a header. In any case, I'm not sure what you would gain with this knowledge. It would be undefined behavior to attempt the access `RandomArray[-1]`, and undefined behavior to even form the pointer `RandomArray - 1`. – ad absurdum Feb 24 '18 at 03:10
  • agree @DavidBowling about UB. – Achal Feb 24 '18 at 03:11
  • @Dúthomhas yes `RandomArray[-1]` need to be typecasted. – Achal Feb 24 '18 at 03:13
0

The sizeof operator works at compile time, except for the case when the operand is variable length array, and the dynamic memory allocation is run time operation. In the expression:

printf("%d  %d",sizeof(RandomArray),sizeof(*RandomArray));

the type of RandomArray is int * and the type of *RandomArray is int.

Hence, the expression is equivalent to:

printf("%d  %d",sizeof(int *),sizeof(int));

for which the sizeof will yield the result as an integer constant and therefore, you will get the same result every time irrespective of the size of memory allocate to RandomArray.

How to find the size of dynamic array

Keep the track of the size from the point where you are allocating memory dynamically.


Beware, you are multiplying the value returned by rand()%11 to the sizeof *RandomArray while allocating memory and rand() may return 0 as well which will lead to malloc(0). Good to know that (from C Standards#7.22.3):

....If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.

H.S.
  • 11,654
  • 2
  • 15
  • 32