Expanding buffer - response to "Determine the size of malloc" query

S

santosh

Harald said:
It is. However, ...


...C90 does not consider any type other than those four an unsigned
integer type. C90's "unsigned integer type" is what C99 calls a
"standard unsigned integer type", and C90 does not recognise what C99
calls "extended integer types". If the implementation supports some
type that behaves exactly as an integer type would, and is represented
exactly the same way, it still cannot be an integer type according to
the C90's definition.

Hmm, seems pretty restrictive to me. Glad that that was rectified with
C99. I suppose this same restriction would make ptrdiff_t potentially
unusable with objects greater than LONG_MAX bytes, though of course,
objects of that size aren't guaranteed in the first place? Wouldn't an
unsigned ptrdiff_t have been more suitable than a signed one?
 
H

Harald van Dijk

Hmm, seems pretty restrictive to me. Glad that that was rectified with
C99. I suppose this same restriction would make ptrdiff_t potentially
unusable with objects greater than LONG_MAX bytes,

Indeed. But there's no guarantee that ptrdiff_t is large enough to hold
the largest difference between two pointers anyway.
though of course,
objects of that size aren't guaranteed in the first place?

True, but (assuming size_t is wide enough) there's nothing stopping you
from passing a large value to malloc, and only using an object of that
size if malloc succeeds.
Wouldn't an
unsigned ptrdiff_t have been more suitable than a signed one?

(p - 1) - p should evaluate to -1. This is not possible if ptrdiff_t were
unsigned.
 
C

Chris Thomasson

[...]
Here's a rewrite where I've improved the code slightly by simplifying
a few bits of it. It now uses offsets rather than lengths and bases
the increase on the requested offset so eliminating some of the
checks. It does require the factor to be greater than or equal to 1.
I'll include the functions and a sample main in one go.
[...]

Three small nit-picks in the test code:

int main(void) {
char *buf1 = NULL;
size_t buf1_limit = 0;
size_t offset;

for (offset = 0; offset < 1000; offset += 200) {
fprintf(stderr, "\n---Checking for offset %d\n", offset);

if (offset >= buf1_limit && ebuf_full(&buf1, &buf1_limit, offset))
{

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If `buf1' is not NULL, and `ebuf_full' returns 1, AFAICT, your leaking
memory here.



fprintf(stderr, "-Ebuf overflow %d/%d bytes", buf1_limit,
offset);
exit(1);
}
buf1[offset] = 'x';
}

fprintf(stderr, "\n---Trim from %d to %d\n", buf1_limit, offset);
if (ebuf_trim(&buf1, &buf1_limit, offset)) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If `buf1' is not NULL, and `ebuf_trim' returns 1, your leaking memory here
as well...



fprintf(stderr, "-Buffer trim to %d failure\n", offset);
exit(1);
}

free(buf1);
return 0;
}




Also, for printing `size_t', its probably "better" to use something like:

printf("sizeof(void*) == %lu\n", (unsigned long)sizeof(void*));



[...]
 
C

CBFalconer

blargg said:
.... snip ...

Does the Windows API prevent a C90 compiler on 64-bit windows from
making unsigned long 64 bits wide? If long must be 32 bits, could
such a compile at least make 2^32-1 the maximum object size, so
that the 32-bit unsigned long would be sufficient to hold the size
of any object?

No, the minimum size of a long is 32 bits. Emphasize, minimum.
 
H

Harald van Dijk

No, the minimum size of a long is 32 bits. Emphasize, minimum.

The C standard allows long to hold more than 32 bits, but that doesn't
mean the Windows API does. It's similar to how you shouldn't expect an
implementation that makes system(NULL) returns 0 to conform to POSIX, even
though any POSIX-conforming implementation is also an conforming C
implementation.
 
S

santosh

blargg said:
Does the Windows API prevent a C90 compiler on 64-bit windows from
making unsigned long 64 bits wide?

IIRC long is constrained to be 32 bits for code which interfaces with
the Windows API.
If long must be 32 bits, could such
a compile at least make 2^32-1 the maximum object size, so that the
32-bit unsigned long would be sufficient to hold the size of any
object?

It could do so, but then you are giving up one advantage of using a
larger address-space computer.

Honestly, I don't know much about 64 bit Windows, so I expect that I'm
either wrong in what I said above or that there are system specific
workarounds. Please don't take my word for this but ask in a group like
<or a suitable group under
the <category.
 
S

santosh

pete said:
santosh said:
Hmm, seems pretty restrictive to me. Glad that that was rectified
with C99. I suppose this same restriction would make ptrdiff_t
potentially unusable with objects greater than LONG_MAX bytes, though
of course, objects of that size aren't guaranteed in the first place?

ptrdiff_t doesn't have that problem with programs that
don't exceed any of the guaranteed minimum environmental limits.

N869
7.18.3 Limits of other integer types
[#2]
-- limits of ptrdiff_t
PTRDIFF_MIN -65535
PTRDIFF_MAX +65535
-- limit of size_t
SIZE_MAX 65535

But, the size of an object doesn't have to exceed LONG_MAX bytes
to have that problem. It only has to exceed 65535 bytes.

So it is. Thanks for that correction.

The POSIX solution, is a signed size_t.
http://bytes.com/forum/thread458286.html

I wonder why ISO C decided not to adopt it? After all, size_t is
specifically meant for counting the bytes of an object, and presumably,
would be suitable for holding pointer offset values too.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top