【问题标题】:Why is malloc not allocating the specified memory amount? [duplicate]为什么 malloc 没有分配指定的内存量? [复制]
【发布时间】:2024-04-30 15:45:02
【问题描述】:

我正在学习 C 动态内存分配,但不明白为什么 malloccalloc 没有分配为 struct 数组和 name char 数组指定的内存量。

代码示例:

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;
}

输出:

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

【问题讨论】:

  • sizeof 不能给出动态分配内存的大小,只能给出指针的大小。您需要自己跟踪动态分配内存的大小。
  • 它正在分配指定的数量。

标签: c printf malloc dynamic-memory-allocation sizeof


【解决方案1】:

第一个输出:char* 在旧计算机(32 位)上使用 4 个字节,在现代计算机(64 位)上使用 8 个字节,因为它是一个指针(不是单个字符)。 第二个输出:它是正确的,因为它是向量单个元素的大小(16 字节) 第三个输出:正确,因为 sizeof 返回的是 char 指针的大小(在 32 位计算机上为 4 个字节)

【讨论】:

    【解决方案2】:

    对于要输出size_t 类型的对象的初学者,您必须使用转换说明符%zu。例如

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

    这两条语句

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

    输出相同的值,因为表达式sizeof(*spaceShipArray) 等价于表达式sizeof(struct spaceShip)

    即解引用指针spaceShipArray 会给出struct spaceShip 类型的对象。指针不知道它们是指向单个对象还是数组的第一个元素。

    如果你想输出分配内存的大小那么你应该写例如

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

    此声明

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

    输出char * 类型指针的大小,因为它是表达式spaceShipArray[0].name 的类型。

    所以程序输出是正确的。

    考虑到您忘记释放为字符数组分配的内存。例如

    free( spaceShipArray[0].name );
    free(spaceShipArray);
    

    【讨论】:

    • 谢谢它的帮助。我还应该释放 malloc、calloc 等未分配的任何其他变量吗?
    • @tec: 不能——你只能free 分配给malloccallocrealloc 的东西。