【问题标题】:Why am I not getting the correct size after using malloc and printing using sizeof?为什么在使用 malloc 和使用 sizeof 打印后我没有得到正确的尺寸?
【发布时间】:2015-06-30 20:08:08
【问题描述】:

这是我的代码。

#include<stdio.h>

typedef struct {
    int a,b;
    } integers;

void main() {
    integers *ptr = (integers *)malloc(10*sizeof(integers));
    printf("%d",sizeof(*ptr)); // prints 8

}

根据我对 Malloc 的了解,上面的代码实际上应该保留 10x8=80 字节的内存供 ptr 指向。

那么为什么使用 sizeof(*ptr) 只能得到 8?如何找到分配给 ptr 的总大小?

【问题讨论】:

  • 因为 sizeof 是编译时构造,而不是运行时,*ptr 也意味着 ptr[0] 是 8 个字节 :)
  • 分配给ptr 的总大小是您请求的大小,您知道它是10*sizeof(integers),除非malloc() 返回您应该经常检查的NULL
  • 是的,但是现在,该 ptr 并没有特别指向任何东西。那么,有什么办法可以知道我使用了多少分配的内存?
  • C语言中malloc返回的指针不需要进行类型转换。
  • 语法上写着sizeof expr(或sizeof (type))只要看看源代码,找出你的表达式size是什么.顺便说一句:main() 应该返回 int。

标签: c


【解决方案1】:

因为您使用的是sizeof(*ptr),您实际上是在询问分配的缓冲区中第一个元素的大小,因此sizeof 将返回ptr第一个元素的大小 (即 32 位系统上的 2x4 字节整数)而不是分配的大小。

另外,请注意,即使您使用 sizeof(ptr),您也会得到 ptr 指针的大小,在 32 位系统上该指针大小为 4 个字节。

【讨论】:

  • 实际上,如果我使用 sizeof(ptr),我得到的输出是 4。
  • @AdarshRao:第 1 部分:sizeof(*ptr) 的值是 integers 类型的单个对象的大小。如果我可以假设您的int 是一个 32 位整数,那么integers 的大小将为8第 2 部分:sizeof(ptr) 的值是指针的大小。这通常是 4 或 8 个字节,具体取决于您的平台。
  • 这是因为您正在使用 32 位架构编译代码,其中指针长度为 32 位(4 字节)。
【解决方案2】:

那么为什么使用 sizeof(*ptr) 只能得到 8?如何找到分配给 ptr 的总大小?

表达式*ptr 的类型是integers - 因此,

sizeof *ptr == sizeof (integers) == sizeof (int) + sizeof (int)

您无法通过查看指针来确定已分配缓冲区的大小(它不存储有关缓冲区大小的任何元数据)。您必须单独跟踪该信息。

编辑

请注意,您可以执行以下操作:

 integers (*foo)[10] = malloc( sizeof *foo );
 if ( foo )
   printf( "sizeof *foo = %zu\n", sizeof *foo );

这将为您提供您期望的结果。在这种情况下,foo 是指向integers数组 的指针,而不是指向integers 的单个实例,因此sizeof *foo 将为您提供分配数组的大小。缺点是您必须在应用下标之前明确取消引用 foo

(*foo)[i].a = some_value();         // or foo[0][i].a
(*foo)[i].b = some_other_value();   // or foo[0][i].b

这通常在您想要分配一个 NxM 数组并确保所有行都是连续的时完成:

integers (*foo)[10] = malloc( 10 * sizeof *foo );

将分配一个 10x10 的 integers 数组,这样行在内存中都是相邻的。

此外,指向 integers 的 10 元素数组的指针与指向 integers 的 11 元素数组的指针不兼容,这使得编写可以使用指向不同数组的指针的函数变得更加困难尺寸。 IOW,如果你有一个函数声明为

void bar( integers (*foo)[10] ) { ... }

只能integers 的 Nx10 数组一起工作。解决这个问题的方法涉及不同程度的疼痛,但这是另一天的话题。

【讨论】:

    【解决方案3】:

    好吧,我知道这个问题已经过时了,但找不到合适的答案,我决定写一个。 当指定sizeof(*ptr) 时,您实际上是在尝试获取存储在指针指向的变量中的数据类型的大小(这里是数组的第一个元素)。在这里,很明显是 8。

    即使您尝试打印 sizeof(ptr),您也会再次打印 指针地址 的大小,在 GCC 编译器中默认为 8 字节,因为数据类型是长无符号的诠释。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 2013-08-29
      • 1970-01-01
      • 1970-01-01
      • 2013-08-19
      相关资源
      最近更新 更多