【问题标题】:malloc(sizeof(s)) allocates less memory than expected?malloc(sizeof(s)) 分配的内存比预期的少?
【发布时间】:2012-04-13 21:10:04
【问题描述】:

嘿,我在 malloc 中使用 sizeof 运算符时遇到问题。例如见下文。代码-

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char * copy(char *s)
{
    char *t=malloc(sizeof(s));
    char *ptr=s;
    int i=0;
    do
    {
        t[i++]=*ptr++;
    }
    while(*ptr!='\0');
    return t;
}
int main()
{
    char *s="hello adsjahsjkdhjkashdkjaskdasldjlasjdlajsdlkjaslkdjalsjdlasjdljasdljasdkljklsdjlasdsadasdasd";
    char *b=copy(s);
    printf("%s\n",b);
    free(b);
    return 0;
}

在 ideone 上,它给出了错误:- * 检测到 glibc ./prog: free(): invalid next size (fast): 0x09bcf008 **

但是当我用 malloc(strlen(s)+1) 替换 malloc(sizeof(s)) 时,程序运行良好。所以有什么问题? 注意:这只是我创建的一个小程序,用于演示我在另一个代码中遇到的问题。

【问题讨论】:

  • 如果malloc ever 分配的数量少于请求的数量(none 除外,在这种情况下它将返回 NULL),那么您已经找到实现中的一个错误——恭喜!

标签: c malloc


【解决方案1】:

运算符sizeof 不会在指针上执行您想要的操作。它会产生您机器上指针的大小(大概是 4 或 8)。

您可以这样想:数组在传递给函数时衰减为指针,而有关其大小的信息“丢失”。


另请注意,您的循环未填充 0 终止符。

【讨论】:

    【解决方案2】:

    您应该在copy 函数中使用strlen 而不是sizeof

    char * copy(char *s)
    {
        char *t=malloc(strlen(s) + 1);
        char *ptr=s;
        int i=0;
        do
        {
            t[i++]=*ptr++;
        }
        while(*ptr!='\0');
        return t;
    }
    

    问题在于 sizeof 没有返回您需要的值,该函数将返回 char *s 的大小(可能是 4 或 8 -> 用于存储该指针的字节)。检查文档链接以更清楚地理解。

    还有一件事,如果你这样做是为了练习你的 C 技能是可以的,但如果你不是,你可能只想使用 strcpy 函数。

    希望对你有帮助。

    【讨论】:

    • 仍然不够...strlen 不计算空终止符。
    • 2 @downvoters,请提出改进​​意见....为什么这个问题还没有选择答案?
    【解决方案3】:

    sizeof(s) 返回 char *s 的大小,即 4(32 位)或 8(64 位)系统。

    【讨论】:

      【解决方案4】:

      具有大小信息的数组和字符串在作为参数传递给函数时会退化为指针丢失其大小属性

      因此,当您计算参数 s 的大小时,它会根据您的位数返回 32/64。

      而不是sizeof,您实际上应该使用strlen 并向其添加一个以容纳空字符。

      而不是

      char *t=malloc(sizeof(s));
      

      试试

      char *t=malloc(strlen(s)+1);
      

      请注意:

      您的代码还有其他设计问题

      1. 当传递一个不应该改变的指针参数时,你应该将它声明为 const。

      2. 通常,如果 cal-lee 忘记释放存储,则返回本地生成的堆存储的地址不是一个好的做法,并且是内存泄漏的主要原因。而是将其作为非常量参数传递给函数。

      【讨论】:

        【解决方案5】:

        sizeof 返回指针的大小(通常为 4 或 8 个字节),而不是指向对象的大小。 (没有办法获得后面的信息。顺便说一下,sizeof 实际上是一个编译时常量。)

        【讨论】:

          【解决方案6】:

          s 是一个指向 char 的指针,因此malloc(sizeof(s)) 为一个指向 char 的指针分配空间——通常是 2-8 个字节,最常见的是 4 个字节。就目前而言,无论您传入的字符串长度如何,它都会始终分配这个固定数量的空间。在您的测试中,您传递的字符串比这长得多,因此您会溢出分配的缓冲区。

          您已经得到了正确答案:在这种情况下,strlen 是查找大小的正确函数。

          【讨论】:

            【解决方案7】:

            malloc 在 中声明,因此我们在任何调用 malloc 的程序中#include 那个头文件。根据定义,C 中的“字节”是适合存储一个字符的存储量,因此上述 malloc 调用为我们提供了与我们要求的一样多的字符。我们可以这样说明生成的指针:

            【讨论】:

              猜你喜欢
              • 2013-10-23
              • 1970-01-01
              • 2021-11-22
              • 2020-05-31
              • 2011-01-03
              • 1970-01-01
              • 2019-06-04
              • 2013-11-14
              相关资源
              最近更新 更多