【问题标题】:Using sizeof() on malloc'd memory [duplicate]在 malloc 的内存上使用 sizeof() [重复]
【发布时间】:2011-01-16 14:57:27
【问题描述】:

可能重复:
newbie questions about malloc and sizeof

我正在尝试将字符串读入程序。当我注意到字符串有时被损坏时,我尝试了以下代码:

 void *mallocated = malloc(100);
 printf("sizeof(mallocated) = %d\n", sizeof(mallocated));

根据我的程序,mallocated 的大小是8,尽管我为它分配了 100 个字节。因此,每当我尝试存储超过 8 个字节的字符串时,第 8 个字节之后的所有内容有时都会消失。为什么会发生这种情况,我该如何预防?

【问题讨论】:

  • sizeof(mallocated) 将为您提供 void* 的大小,在您的 64 位系统上为 8 个字节。如何使用 strcpy 将字符串分配给该变量?
  • 您的结论也是错误的,在第 8 个“字节”(不是位)之后写入的任何内容有时都不会随机消失。

标签: c malloc sizeof


【解决方案1】:

因为“字符串”指针的大小是 8 个字节。以下是一些使用 sizeof() 及其适当“大小”的示例。 size_of() 这个词有时会欺骗不习惯使用它的人。在您的情况下,指针的大小是 8 个字节。下面是典型 32 位系统上的表示。

sizeof (char)   = 1
sizeof (double) = 8
sizeof (float)  = 4
sizeof (int)    = 4
sizeof (long)   = 4
sizeof (long long)  = 8
sizeof (short)  = 2
sizeof (void *) = 4

sizeof (clock_t)    = 4
sizeof (pid_t)  = 4
sizeof (size_t) = 4
sizeof (ssize_t)    = 4
sizeof (time_t) = 4

Source

您忽略了如何确定您的字符串正在消失(字符数组)。它可能被传递给一个函数,您需要将显式长度作为变量传递或在某处跟踪它。使用sizeof() 不会告诉你这一点。

请参阅我的previous question,您甚至会发现我缺乏初步的了解。

【讨论】:

  • 感谢您的帮助。该程序的问题并不像我想象的那样(曾经发生过吗?),但您的建议非常有用。
【解决方案2】:

在 C89 中,sizeof 运算符仅在编译时查找 变量 的大小(在本例中为 8 字节的 void 指针)。它的工作方式与您对普通数组的预期一样,因为它们的大小在编译时是已知的。

char arr[100]; // sizeof arr == 100
char *p = arr; // sizeof p == 4 (or 8 on 64-bit architectures)
char *p = malloc(100); // sizeof p == 4 (or 8). Still!

要知道堆分配内存的大小,你需要手动跟踪它,sizeof 帮不了你。

【讨论】:

  • 这不是真的。在 C99 中,sizeof 返回可变长度数组的大小,很多情况下只能在运行时确定。
  • 谢谢,我从答案中排除了 C99 案例以使事情更简单。
【解决方案3】:

sizeof 返回您给它的指针 (void *) 的大小,而不是您分配的内存大小。如果您想稍后使用它,您必须将内存的大小存储在一个单独的变量中。

【讨论】:

    【解决方案4】:

    你不能。正如所指出的,你可以得到void * mallocated 的大小,但这并不能告诉你太多。

    无法获得 malloed *mallocated 的大小。也就是说,没有返回 100 的函数调用(在您的示例中)-除非您编写自己的内存管理例程。

    最简单的就是在某个地方记住它......也许......

    stuct {
      void *data;
      unsigned int size
     } myStructureWhichRemebersItsSize;
    
    myStructureWhichRemebersItsSize *someData;
    someData.data = malloc(100);  // and check for NULL
    someData.size = 100;
    

    【讨论】:

    • “你无法获得 malloed 的大小”... 不正确,这取决于您的 C 库。在 MS 的 CRT STDLIB 下,您只需调用 _msize(*mallocated) 即可获得 OP 寻求的“100”。
    • +1 感谢您提供信息。我不使用MS,所以不知道。一个有用的功能,很高兴在更多地方看到。当然,编译器可能会在幕后生成我所描述的结构。
    • 如果 someData 被声明为指针,您必须使用“->”运算符访问其字段
    【解决方案5】:

    void* 是内存中位置的类型,如果您不知道它包含什么。应该避免。

    char* 是指向内存中某个位置的值的类型,该位置包含char。识别内存中的位置需要 8 个字节。

    sizeof 告诉您特定类型占用多少字节。不是使用malloc 分配了多少内存,而是编译器知道应该 采用的类型有多少。将sizeof 应用于值通常被认为是不好的风格,正如这里其他人提到的那样,有时会调用 C99 中的智能行为。

    char[100] 包含 100 个字符的值的类型。 char[100] a; 是堆栈上的 100 个 chars 的字符串。

    char(*)[100] 是指向包含 100 个字符的值的指针的类型。 char(*b)[100]; 使 b 指向 100 个字符,可能在堆上。你可能想要的是

    char (*s)[100] = malloc( sizeof( char[100] ) );
    printf( "%u byte pointer to %u bytes of size %u elements\n",
      sizeof s, sizeof *s, sizeof **s );
    

    【讨论】:

      猜你喜欢
      • 2015-11-22
      • 2021-11-22
      • 2017-05-13
      • 2013-02-19
      • 1970-01-01
      • 2020-11-01
      • 2017-03-05
      相关资源
      最近更新 更多