c语言 - 为什么当我传递"big"大小时,calloc 总是返回 NULL?



这是我的代码(它是并且必须是纯C(:

unsigned long buffSize = 65536; /* 64 KB */
char *block;
block = calloc(1, buffSize);
if (block == NULL)
{
    /* This is always triggered */
}

我想要一个 64 KB 的零内存,我将在应用程序的其他位置循环使用。

不幸的是,calloc总是返回NULL.当我用 64(字节(使用它时,它可以工作。

不确定如何像我的例子一样分配"更大"的内存块?

编辑:阅读评论后,这里有一些澄清:

  1. mallocmemset具有相同的行为,具有相同的buffSize
  2. sizeof(size_t) == 2sizeof(unsigned long) == 4,所以它是 16 位的。
  3. 目标平台是 MS-DOS 6.22。

那么在 16 位系统下,如何创建 64 KB 零填充的char *

你说过sizeof (size_t) == 2(这是针对MS-DOS 6.22的(。

这意味着size_t的最大值为 65535

unsigned long buffSize = 65536; /* 64 KB */

到目前为止没有问题。 unsigned long必须至少为 32 位(在您的系统上为 32 位(,因此它可以轻松地保存值65536

char *block;
block = calloc(1, buffSize);

calloc的两个参数都是类型 size_t 。任何不属于类型 size_t 的参数都会被隐式转换。将65536转换为size_t产量0。因此,您请求分配 0 字节。此类分配的行为是实现定义的;它可以返回 null 指针,也可以返回唯一的非 null 指针,类似于 malloc(1) 只是您不一定不能取消引用它。您的实现显然是前者。

calloc 接受两个参数,均为 size_t 型。它们的值不是简单地相乘以产生类型 size_t 的结果。相反,calloc必须成功分配指定的字节数,否则无法分配并返回空指针。

原则上,您可以编写:

block = calloc(64, 1024);

或类似的东西。如果成功,它将分配一个 65536 字节的对象。

但由于size_t只有 16 位,这几乎肯定意味着实现不能创建最多大于 65535 字节的对象。实际上并没有禁止创建大于 SIZE_MAX 字节的对象,但任何能够这样做的实现几乎肯定会使其size_t更大,以便它可以表示任何对象的大小。

( SIZE_MAX 是类型 size_t 的最大值。它是在<stdint.h>中定义的宏,由C99标准引入。您的实现可能不支持<stdint.h> 。表达式 ((size_t)-1) 是等效的。

你可能不走运,除非你使用不同的实现(这可能意味着使用相同的编译器和不同的选项(。

也许您可以重新设计程序,以便它可以使用两个 32768 字节的对象,而不是单个 65536 字节的对象(尽管也可能不支持(。

MS-DOS 系统支持(支持?(多种内存模型,其中一些可能允许您执行所需的操作。我不知道细节。有关详细信息,请参阅编译器的文档。

对于 16 位实数模式,您可能需要指定"巨大"模型,该模型使用远指针来支持大小> 65536 的数组。紧凑或大型模型可能有效,使用单个固定段值和可变偏移量来处理缓冲区大小 65536。我不知道你正在使用什么工具集,但应该有一个命令行参数来指定程序将使用的内存模型。对于Microsoft 16 位实模式编译器,参数为/AH 表示大型,/AC 表示紧凑,/AL 表示大型。

维基链接: 英特尔内存模型

相关内容

  • 没有找到相关文章

最新更新