-1

I'm learning C dynamic memory allocation and can't figure out why malloc or calloc are not allocating the amount of memory specified for the struct array, nor for the name char array.

Code example:

struct spaceShip{
  long long int distance; // 8 bytes
  int numParts; // 4 bytes
  char *name; // 1 byte
}; // 13 bytes total

int main (int argc, char *argv[]){

  int amount=10;
  struct spaceShip *spaceShipArray;

  printf("size of struct spaceShip = %d bytes\n", sizeof(struct spaceShip));

  spaceShipArray = malloc(amount * sizeof(*spaceShipArray));
  printf("size of spaceShipArray = %d bytes\n", sizeof(*spaceShipArray));

  spaceShipArray[0].name = malloc(100 * sizeof(char));
  printf("size of name char array = %d \n", sizeof(spaceShipArray[0].name));

  free(spaceShipArray);

  return 0;
}

Output:

size of struct spaceShip = 16 bytes //I guess because of the pagination mechanism it takes more? 
size of spaceShipArray = 16 bytes // not ok. should be 160
size of name char array = 4 // not ok. should be 100
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
tec
  • 999
  • 3
  • 18
  • 40
  • 4
    `sizeof` cannot give the size of dynamically allocated memory, only the size of the pointer. You need to track the size of dynamically allocated memory yourself. – kaylum Oct 24 '21 at 20:28
  • 5
    It is allocating the amount specified. – tkausl Oct 24 '21 at 20:28

2 Answers2

2

For starters to output objects of the type size_t you have to use the conversion specifier %zu. For example

printf("size of struct spaceShip = %zu bytes\n", sizeof(struct spaceShip));

These two statements

printf("size of struct spaceShip = %zu bytes\n", sizeof(struct spaceShip));
printf("size of spaceShipArray = %zu bytes\n", sizeof(*spaceShipArray));

output the same value because the expression sizeof(*spaceShipArray) is equivalent to the expression sizeof(struct spaceShip).

That is dereferencing the pointer spaceShipArray gives an object of the type struct spaceShip. Pointers know nothing whether they point to a single object or a first element of an array.

If you want to output the size of the allocated memory then you should write for example

printf("size of spaceShipArray = %zu bytes\n", amount * sizeof(*spaceShipArray));

This statement

printf("size of name char array = %zu \n", sizeof(spaceShipArray[0].name));

outputs the size of a pointer of the type char * because it is the type of the expression spaceShipArray[0].name.

So the program output is correct.

Take into account that you forgot to free the memory allocated for a character array. For example

free( spaceShipArray[0].name );
free(spaceShipArray);
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thx it helped. Should I free also any other variable not assigned by malloc, calloc etc? – tec Oct 24 '21 at 20:58
  • 1
    @tec: No - you can only `free` things that have been allocated with `malloc`, `calloc`, or `realloc`. – John Bode Oct 24 '21 at 21:16
0

First output: char* uses 4 bytes on a old computer (32bit) or 8 bytes on a modern computer (64bit) because it is a pointer (not a single char). Second output: it is correct because it's the size of a single element of the vector (16 byte) Third output: it is correct because sizeof returns the size of the char pointer (4 bytes on a 32bit computer)

Nicola Revelant
  • 102
  • 1
  • 3