1

I'm having some trouble understanding the difference between these two code segments: I allocate space for an array of integers dynamically within my code with the following statement

int *arr = calloc(cnt, sizeof(int));

In another function, where I pass in arr, I would like to determine the size (number of elements) in arr. When I call

int arr_sz = sizeof(arr)/sizeof(int);

it only returns 1, which is just the number of bytes in an int for both arguments I am assuming (4/4)=1. I just assumed it would be the same as using an array

  int arr[8];
  int arr_sz = sizeof(arr)/sizeof(int);

which returns the actual number of elements in the array.

If anyone could clear this up, that would be great. Thanks!

akshayk07
  • 2,092
  • 1
  • 20
  • 32
mike
  • 3,339
  • 6
  • 30
  • 34
  • Arrays are just pointers the compiler can help you manage. Once they pass through a function, or if dynamically allocated, the compiler can't help you. – salezica Mar 30 '11 at 20:22
  • @Santiago Lezica:: *Arrays are just pointers the compiler can help you manage* --> This is strange. Please go through - http://www.lysator.liu.se/c/c-faq/c-2.html – Sadique Mar 30 '11 at 20:27
  • You cut half my comment in your quote. The other half was important. There is obviously a difference between char a[10] and char* a, different things happen when you type one line or the other. – salezica Mar 30 '11 at 20:34
  • possible duplicate of [Is array name a pointer in C?](http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c) – Jens Gustedt Mar 30 '11 at 21:18
  • @Jens Gustedt:: Nopes `sizeof` and `dynamic` memory allocation still need an answer. – Sadique Mar 30 '11 at 21:51

8 Answers8

8
int *arr;   ----> Pointer
int arr[8]; ----> Array

First up what you got there - int *arr is a pointer, pointing to some bytes of memory location, not an array.

The type of an Array and a Pointer is not the same.

In another function where I pass in arr, I would like to determine the size (number elements) in arr. When I call

int arr_sz = sizeof(arr)/sizeof(int);

it only returns 1, which is just the number of bytes in an int for both arguments I am assuming (4/4)=1. I just assumed it would be the same as using an array

Even if it is assumed to be an Array -- that's because Arrays get decayed into pointers when passed into functions. You need to explicitly pass the array size in functions as a separate argument.

Go through this:

Sizeof an array in the C programming language?

There is a difference between a static array and dynamic memory allocation.

The sizeof operator will not work on dynamic allocations. AFAIK it works best with stack-based and predefined types.

Community
  • 1
  • 1
Sadique
  • 22,572
  • 7
  • 65
  • 91
  • Was arr ever an array? It's been a while since I've done C and my memory is not good but I did not think the way arr was declared and initialised would have ever made it an array? – Dan Kendall Mar 30 '11 at 20:19
  • This. There is no way to dynamically determine the size of an array in C – David Brown Mar 30 '11 at 20:20
2

well, int *arr declares a pointer, a variable which keeps the address of some other variable, and its size is the size of an integer because it's a pointer, it just have to keep the address, not the pointee itself.
int arr[8] declares an array, a collection of integers. sizeof(arr) refers to the size of the entire collection, so 8*sizeof(int).
Often you hear that "array and pointers are the same things". That's not true! They're different things.

BlackBear
  • 22,411
  • 10
  • 48
  • 86
1

Mike,

arr is a pointer and as such, on your system at least, has the same number of bytes as int. Array's are not always the same as pointers to the array type.

Dan Kendall
  • 702
  • 5
  • 22
0

sizeof(arr) is the same as sizeof(int*), i.e. the size of a single pointer. You can however calculate arr_sz as ... cnt!

phihag
  • 278,196
  • 72
  • 453
  • 469
0

*arr is not the same as arr[8] since it's size is not known in compile time, and sizeof is a function of the compiler. So when your arr is *arr sizeof will return the size of the pointer (sizeof(int *))in bytes, while when your arr is arr[8], the sizeof will return the size of array of 8 integers in bytes (which is sizeof(int) * 8).

When you pass a pointer to array to a function, you must specify its size, because the compiler can't do it for you. Another way is to end the array with null element, and perform a while loop.

MByD
  • 135,866
  • 28
  • 264
  • 277
0

If you have int arr1[8] the type of arr1 (as far as the compiler is concerned) is an array ints of size 8.

In the example int * arr2 the type of arr2 is pointer to an integer.

sizeof(arr1) is the size of an int array
sizeof(arr2) is the size of an int pointer (4 bytes on a 32 bit system, 8 bytes on a 64 bit system)

So, the only difference is the type which the compiler thinks that variable is.

skabbes
  • 890
  • 7
  • 17
0

You can't use sizeof with memory pointers:

int *arr = calloc(cnt, sizeof(int));

But it's ok to use it with arrays:

int arr[8];
karlphillip
  • 92,053
  • 36
  • 243
  • 426
0

I got into the same problem today and was going to ask new question but found my answer in this post. Just posting my answer as I and even others can found it useful Here is my code:

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

struct Data
{
    int* array;
};

    int main(int argc, char* argv[])
    {
        struct Data *data = (struct Data*)malloc(sizeof(struct Data));
    
        data->array = (int*)malloc(sizeof(int) * 10);
    
        printf("\ndata struct size: %u", sizeof(data));
        printf("\narray size: %u", sizeof(data->array));
    
        free(data->array);
        free(data);
    
        getchar();
        return 0;
    }

Output:

data struct size: 4
array size: 4

Here I was expecting the total size of array which could be 40 but as sizeof operator does not work with dynamically allocated arrays it only returns the size of int pointer which is 4. Just for information, I am using Visual Studio 2017 with Windows 10