当我写下面的代码时,我得到了奇怪的答案。
#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上运行它。
答案 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
。尽管它“正好”发挥作用,但稍后软件维护也不会那么令人困惑。这可能是未定义的行为。