1

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

#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 将参数作为字节数。所以在这里我输入了 1 个字节,我知道在我的机器上 int 需要 4 个字节进行存储(通过 sizeof() )但代码仍然没有显示错误,我可以输入一个 int 值。即使我输入 3333333 它也不会抱怨。如果我使用 malloc() 而不是 malloc(1) gcc 抱怨 malloc 的参数太少但仍然给出相同的结果。我无法理解这种行为。有人请澄清一下。

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

4

5 回答 5

3

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

int *p=malloc(1);

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

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

然后将有足够的空间容纳整数。

当您在分配的内存范围之外运行时,C 不会警告您,因此您需要仔细管理 malloc 的大小。

于 2013-03-01T05:46:08.987 回答
2

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

这实际上意味着在您询问的 1 个字节之后有 7 个或 15 个字符的额外空间。你应该使用它吗?只有在同意的成年人的情况下才能关起门来。

在这些方法中,顺便说一句,有恢复到系统调用,它在物理边界分配页面——试试例如 malloc(1<<28); (256 兆字节);malloc 的一些实现从一个特殊的缓冲区分配 1-8 或 1-16 个字节,然后为更大的块在内部保留 N+8 或 N+16(再次向上舍入到下一个边界)用于簿记数据。

如果您覆盖保留区域,这些数据将被丢弃。它会导致稍后在一些 malloc / free 中进行断言,并导致重复并且很快就会关闭关于 SO 的非常模糊的问题。

嵌入式系统上的malloc可以被编程为不能回收;它可以简单地通过

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

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

于 2013-03-01T06:53:50.770 回答
0

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

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

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

于 2013-03-01T05:43:46.543 回答
0

为您的需要分配足够的内存是您的责任。编译器不会检查您是否正在访问您分配的内存之外的内存。

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

如果您调用malloc(1),编译器无需抱怨,因为 malloc 需要一个参数(内存大小),而您正在传递它..

但是当你打电话时malloc(),情况就不同了,编译器会抱怨..

于 2013-03-01T05:46:07.803 回答
0

的实现malloc不太可能给你一个字节。它可能会被调整到最接近的单词大小,这意味着sizeof(int)将适合该空间的东西。很像:

struct foo {
    char a;
};

sizeof(struct foo)可能是字长。不用说,您应该分配更多空间(例如malloc(sizeof(int))),因为您想阅读int. 尽管事实上它“碰巧”起作用,但以后对软件维护的困惑会减少。这可能是未定义的行为。

于 2013-03-01T05:47:14.527 回答