How to pass a pointer to sizeof? Am I working correctly in this example ?:

int *arr; arr = (int*) malloc(5 * sizeof(*arr)); printf("Выделенная память равна: %d байт\n", 5 * sizeof(*arr)); //заполним массив .... //обнулим значения в этой памяти memset(arr, 0, 5 * sizeof(*arr)); 

Since arr is a pointer, then you need to pass with a star, right?

  • 2
    The result of sizeof is of type size_t , for which reason it cannot be passed to printf with the format specifier %d - the behavior is undefined. The correct format specifier for size_t is %zu - AnT
  • @Ant hmm, if you set% zu in the studio, the value of the variable will not be displayed. - Tkas
  • Depends on the Studio version. %zu is C99, whose support appeared in VS2013 and was completed in VS2015. In VS2015, %zu works reddened, although it is not described at the docks. If there is no support for %zu , then printf("%llu\n", (unsigned long long) (5 * sizeof *arr)); is better printf("%llu\n", (unsigned long long) (5 * sizeof *arr)); - AnT September
  • @AnT clear, I have 2012 studio. - Tkas

4 answers 4

sizeof(<элемет>) Returns the size in bytes of memory for the element to be allocated.

If We work in a 32-bit system, then the following constructions do the same thing, allocate 20 bytes in memory.

 void * v = malloc(20); char * c = (char *)malloc(20); int * i = (int *)malloc(5 * sizeof(int)); int ** pi = (int **)malloc(5 * sizeof(int *)); struct s{ char c; int i; long long int lli; int * pi; short int s; char s; }__attribute__((packed)); struct * s = (struct s *)malloc(5 * sizeof(struct s*)); struct * s = (struct s *)malloc(sizeof(struct s)); 

But to describe these expressions can be so.

void * v = malloc(20); - create a pointer to an object of any type and allocate 20 bytes

char * c = (char *)malloc(20); - create a pointer to a string and select a string by 20 characters.

int * i = (int *)malloc(5 * sizeof(int)); - create a pointer to an int type and allocate memory for 5 int elements

int ** pi = (int **)malloc(5 * sizeof(int *)); - create a user to an array of int pointers and allocate memory for 5 pointers.

struct * s = (struct s *)malloc(5 * sizeof(struct s*)); - create a pointer to an array of pointers to the structure s.

struct * s = (struct s *)malloc(sizeof(struct s)); - create a pointer to the structure s.

In programming, there is no such thing так принято , there is a standard language that can be used.

    Since arr is a pointer, then you need to pass with a star, right?

    Essentially true, but the wording is incorrect :) You need not to "pass the pointer", but to find out the size of the array element. Traditionally done like this:

     arr = (int*) malloc(5 * sizeof(int)); 

    But since the *arr construction in this case returns the first element of the arr array, then with incorrect input, we got the correct result :)

    // reset values ​​in this memory

    man calloc !


    Checking:

     int main() { int *arr; arr = (int*) malloc(5 * sizeof(*arr)); printf("Allocated %zu bytes\n", 5 * sizeof(*arr)); free(arr); arr = (int*) malloc(5 * sizeof(int)); printf("Allocated %zu bytes\n", 5 * sizeof(int)); free(arr); return 0; } 

    Conclusion:

     Allocated 20 bytes Allocated 20 bytes 
    • Comments are not intended for extended discussion; conversation moved to chat . - Nick Volynkin

    In your case there is no difference, the memory will be allocated the same in any case - 4 bytes per element. But if the type was different, then everything changes.

    Yes, in the above code you need to pass with an asterisk, so that sizeof would count the size of the type, and not the size of the pointer.

    • In your case there is no difference, the memory will be allocated the same in any case - 4 bytes per element. - Not certainly in that way. sizeof(int) and sizeof(int*) can oh how different. - PinkTux
    • @Pink Tux yes, vary. an int without a star gives 8 bytes, but with a star 4. This is not clear to me: why is that? - Tkas
    • one
      @Tkas, because the size of int in your architecture is 4 bytes, and the size of int* (that is, pointer to int ) is 8 bytes. - PinkTux
    • @Pink Tux is accurate, since the pointer also stores its address. Thank. - Tkas
    • one
      sizeof(*arr) - here is the size of int a, and not the pointer. *arr is arr[0] , which is int. The pointer size would be simply arr when transmitted. - Qwertiy
     sizeof(*arr) 
     sizeof(int) 
     memset(arr, 0, 5 * sizeof(*arr)); 
     free(arr); 

    reset values ​​in this memory

    This is not required for her release. Moreover, if the compiler is sure that the memory is not used after this reset, he has the right not to execute it. To erase sensitive data, use a special function.

    https://habrahabr.ru/company/pvs-studio/blog/272243/ - paragraph 3.
    https://habrahabr.ru/company/pvs-studio/blog/281072/

    • And what function do you mean? - Tkas
    • one
      Added links. Quote from one of them: In Visual Studio, for example, you can use RtlSecureZeroMemory. Starting from C11, there is a memset_s function. If necessary, you can create your own safe function. - Qwertiy
    • @Tkas, if zeroing is needed for working with memory, then it makes sense to use calloc instead of malloc/memset . If to erase the data, so that after the release of memory or upon completion of the program, an evil villain cannot get to them - another question. - PinkTux
    • @PinkTux I don’t really understand in my particular case the difference between malloc and calloc. They do the same thing when allocating memory. - Tkas
    • Thanks for the links, very interesting information. - Tkas