malloc(sizeof(s))分配的内存少于预期?

时间:2012-04-13 21:10:05

标签: c malloc

嘿,我在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():下一个尺寸无效(快速):0x09bcf008 * *

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

7 个答案:

答案 0 :(得分:6)

运算符sizeof无法在指针上执行您想要的操作。它会产生机器上指针的大小(类似于4或8)。

你可以这样想:当传递给一个函数时,数组会衰减到一个指针,并且有关它的大小的信息是&#34;丢失&#34;。


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

答案 1 :(得分:6)

您应该在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功能。

希望它有所帮助。

答案 2 :(得分:4)

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

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

而不是sizeof,您应该实际执行strlen并为其添加一个以容纳空字符。

而不是

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

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

请注意:

您的代码存在其他设计问题

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

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

答案 3 :(得分:4)

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

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

答案 6 :(得分:0)

malloc是声明的,所以我们#include任何调用malloc的程序中的头。根据定义,C中的“字节”是适合存储一个字符的存储量,因此上面的malloc调用给出了与我们要求的字符数一样多的字符。我们可以像这样说明结果指针: