This is my code (it is and must be pure C):
unsigned long buffSize = 65536; /* 64 KB */
char *block;
block = calloc(1, buffSize);
if (block == NULL)
{
/* This is always triggered */
}
I want a 64 KB of zeroed memory that I will use in a loop somewhere else in my application.
Unfortunatly calloc
always return NULL
. When I use it with 64 (bytes) it works.
I'm not sure how to allocate "bigger" memory blocks like in my example?
Edit: After reading comments, here are some clarifications:
malloc
and memset
have the same behavior with the same buffSize
.sizeof(size_t) == 2
while sizeof(unsigned long) == 4
so it's 16-bit.So under a 16 bits system how can you create a char *
of 64 KB zero-filled?
You've said that sizeof (size_t) == 2
(this is for MS-DOS 6.22).
That means that the maximum value of size_t
is 65535
.
unsigned long buffSize = 65536; /* 64 KB */
No problem so far. unsigned long
must be at least 32 bits (and is 32 bits on your system), so it can easily hold the value 65536
.
char *block;
block = calloc(1, buffSize);
Both arguments to calloc
are of type size_t
. Any argument that's not of type size_t
is implicitly converted. Converting 65536
to size_t
yields 0
. So you're requesting an allocation of 0 bytes. The behavior of such an allocation is implementation-defined; it can return a null pointer, or it can return a unique non-null pointer, similar to malloc(1)
except that you can't necessarily dereference it. Your implementation apparently does the former.
calloc
takes two arguments, both of type size_t
. Their values are not simply multiplied to yield a result of type size_t
. Instead, calloc
must either successfully allocate the number of bytes specified or fail to do so and return a null pointer.
In principle, you can write:
block = calloc(64, 1024);
or something similar. If it succeeds, it will allocate a 65536-byte object.
But since size_t
is only 16 bits, that almost certainly means that the implementation cannot create objects bigger than at most 65535 bytes. There's no actual prohibition against creating objects bigger than SIZE_MAX
bytes, but any implementation that's able to do so would almost certainly make its size_t
bigger, so that it can represent the size of any object.
(SIZE_MAX
is the maximum value of the type size_t
. It's a macro defined in <stdint.h>
, which was introduced by the C99 standard. Your implementation probably doesn't support <stdint.h>
. The expression ((size_t)-1)
is equivalent.)
You're probably out of luck, unless you use a different implementation (which might mean using the same compiler with different options).
Perhaps you can redesign your program so it can use, for example, two 32768-byte objects rather than a single 65536-byte object (though that might not be supported either).
MS-DOS systems support (supported?) multiple memory models, some of which might permit you to do what you want. I don't know the details. Consult your compiler's documentation for more information.