无法理解为什么c中的malloc函数正在如下所述?

时间:2013-03-01 05:41:27

标签: c malloc

当我写下面的代码时,我得到了奇怪的答案。

#include<stdio.h>
#include<stdlib.h>
main()
{
int *p=malloc(1);
if(p==0)
printf("memory not assigned\n");
else
{
printf("memory assigned\n");
printf("enter an int\t");
scanf("%d",p);
printf("\n You entered number %d",*p);
printf("\nIt has been stored at-%p",p);
}
}

我认为malloc将参数作为byte的数量。所以我输入1个字节,我知道在我的机器上int需要4个字节用于存储(通过sizeof())但是代码仍然没有显示错误,我可以输入一个int value。如果我输入3333333它不会抱怨。如果我使用malloc()而不是malloc(1)gcc抱怨malloc的参数太少但仍然给出相同的结果。我无法理解这种行为。请有人澄清它

我通过虚拟框在gcc上运行它。

5 个答案:

答案 0 :(得分:3)

如你所说,如果你这样做:

int *p=malloc(1);

仅分配1个字节。由于int大于1个字节,它将超出分配的内存并为您提供未定义的行为。如果你这样做:

int *p=malloc(sizeof(int));

然后将有足够的空间用于整数。

当你在边界分配内存之外运行时,C不会发出警告,所以你需要仔细管理malloc的大小。

答案 1 :(得分:2)

“现代”环境中的Malloc对不同长度使用不同类型的分配策略。常见的是,在32位环境中,事实上的标准是将所有内容对齐8字节,现在在x64时代以16字节的粒度对齐。

这实际上意味着在您询问的1个字节后有7或15个字符的额外空格。你应该用吗?只有在闭门的情况下同意成年人。

在这些方法中,顺便提一下,还有系统调用,它在物理边界分配 pages - 例如,尝试的malloc(1 <<;&LT; 28); (256 Mb); malloc的某些实现从特殊缓冲区分配1-8或1-16个字节,反过来又为内部N + 8或N + 16(再次向上舍入到下一个边界)保留较大的块用于簿记数据。

如果您覆盖保留区域,这是将被删除的数据。它会在稍后的某些malloc / free中导致ASSERT,它会导致重复,很快就会在SO上关闭非常模糊的问题。

嵌入式系统上的Malloc可编程为无法回收;它可以简单地通过

实现
void *malloc_embedded(size_t a) {
    static uint8_t *heap=_heap;
    uint8_t *old=heap; heap+=a;
    return old;
}

这可能与您预期的一样,但用例更加有限 - 可以修改此方法以释放最后分配的元素,但不能再使用。

答案 2 :(得分:0)

未定义的行为? malloc(1)返回一个空闲的块或大小为1的字节,除了返回的块之外可能还有更多的块,你的整数被写入。(押韵!)

显然,malloc()需要1个参数。如果你没有提供,gcc 抱怨,所有其他符合C标准的编译器都会抱怨。

如果您想要sizeof(int)个字节,那么:malloc(sizeof(int))

答案 3 :(得分:0)

您有责任为您的需求分配足够的内存。编译器不会检查您是否正在访问超出所分配内存的内存。

如果您分配x内存量,要存储大小大于x的值,您的应用程序可能(可能不会)在运行时崩溃。这是未定义的行为。

如果你调用malloc(1),编译器就不需要抱怨了,因为malloc需要一个参数(内存大小),而你传递它...

但是当你打电话给malloc()时,情况就不一样了,编译器也抱怨......

答案 4 :(得分:0)

malloc的实现不太可能只给你一个字节。它的大小可能会达到最接近的字大小,这意味着sizeof(int)的某些内容将适合该空间。很像:

struct foo {
    char a;
};

sizeof(struct foo)可能是单词大小。毋庸置疑,您应该分配更多空间(例如malloc(sizeof(int))),因为您想要阅读int。尽管它“正好”发挥作用,但稍后软件维护也不会那么令人困惑。这可能是未定义的行为。