469,085 Members | 1,027 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,085 developers. It's quick & easy.

substitute for string 0 termination

The C-faq says that "The malloc/free implementation remembers the size
of each block allocated and returned, so it is not necessary to remind
it of the size when freeing."

Could that length information somehow be used as a substitute for
0-termination of strings?

Felix
Nov 14 '05 #1
35 2342
Felix Kater wrote:
The C-faq says that "The malloc/free implementation remembers the size
of each block allocated and returned, so it is not necessary to remind
it of the size when freeing."

Could that length information somehow be used as a substitute for
0-termination of strings?

Felix


The length that the implementation keeps track of is the size of the
block allocated by malloc() which, assuming success, will be at least
the size you requested. Of course, you can store strings which are
shorter than this without any trouble, and the length will be different.
Furthermore, the way the implementation decides to keep track of the
size of the block returned by malloc() is up to the implementation. So
any hack which you discover for reading the actual size allocated is
completely non-portable. You could, however, use a structure where the
length (of the string) is stored, and use that instead of a terminating
0. However, since the C library functions require 0 termination for
strings, you'll have a much more difficult time passing the string to
these functions. It would make sense, though, to keep track of the
length if you anticipate repetetive calls to strlen() when the length is
not changing, thus avoiding needless O(n) operations.

Hope that helps,
--John
Nov 14 '05 #2
Yes, you could speed up length tests by storing the length before the
first character like this. The "fast" strings are still
zero-terminated, so they work with the CRT string functions.

char * makeFastString( char *regularString )
{
size_t len, *p;
len = strlen( regularString );
p = malloc( len + 1 + sizeof( size_t ) );
if( !p )
return NULL;
*p = len;
strcpy( (char *)( p + 1 ), regularString );
return (char *)( p + 1 );
}

size_t lengthOfFastString( char *fastString )
{
size_t *p = (size_t *) fastString;
return *( p - 1 );
}

void deleteFastString( char *fastString )
{
size_t *p = (size_t *) fastString;
free( p );
}

Nov 14 '05 #3
Oops typo: free( p ) should be free( p - 1 )

Nov 14 '05 #4
al******@hotmail.com wrote:

Yes, you could speed up length tests by storing the length before the
first character like this. The "fast" strings are still
zero-terminated, so they work with the CRT string functions. void deleteFastString( char *fastString )
{
size_t *p = (size_t *) fastString;
free( p );
}


I think

free(fastString);

is what you really want to use, instead of

deleteFastString(fastString);

--
pete
Nov 14 '05 #5
Yeah there was a typo. Unfortunately you can't edit posts here.

Nov 14 '05 #6
al******@hotmail.com writes:
Yeah there was a typo. Unfortunately you can't edit posts here.


Usenet has a `supersedes' feature that you could use.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 14 '05 #7
Mac
On Wed, 26 Jan 2005 00:11:28 +0100, Felix Kater wrote:
The C-faq says that "The malloc/free implementation remembers the size
of each block allocated and returned, so it is not necessary to remind
it of the size when freeing."

Could that length information somehow be used as a substitute for
0-termination of strings?

Felix


In some hypothetical alternate universe, the committee responsible for
defining the C programming language could have opted to handle strings
differently.

In the universe we actually inhabit, the size of a block returned by
malloc can never be accessed directly by the programmer if the code is to
remain portable.

In any event, there are plenty of times when you don't want to malloc a
chunk of memory to be exactly the size of your string.

However, you could always define a struct wrapper for your strings
which remembers how big they are. See the untested fragment below.

struct my_string
{
size_t size;
char *s;
};

struct my_string *new_my_string(size_t size)
{
struct my_string *new_string;

new_string = malloc(sizeof *new_string);
if (new_string == NULL)
return NULL;
new_string->s = malloc(size);
if (new_string->s == NULL)
{ free(new_string);
return NULL;
}
new_string->size = size;
return new_string;
}

That kind of thing.

--Mac

Nov 14 '05 #8
Felix Kater wrote:
The C-faq says that "The malloc/free implementation remembers the size
of each block allocated and returned, so it is not necessary to remind
it of the size when freeing."

Could that length information somehow be used as a substitute for
0-termination of strings?
...


No.

Firstly, C standard library does not provide user with any means to
access this information.

Secondly, memory allocation functions are not guaranteed to allocate
exactly the requested amount of memory. Successful allocation requiest
might allocate more memory than was actually requested, which is
perfectly legal in C.

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #9

"Andrey Tarasevich" <an**************@hotmail.com> schreef in bericht
news:10*************@news.supernews.com...
Firstly, C standard library does not provide user with any means to
access this information.
Secondly, memory allocation functions are not guaranteed to allocate
exactly the requested amount of memory. Successful allocation requiest
might allocate more memory than was actually requested, which is
perfectly legal in C.


I understand this of course, but still I'd like to know why a function like
memsize can't be introduced in the std library. Maybe more bytes are
allocated than requested, a program shouldn't invoke undefined behaviour
when those extra bytes are overwritten right.
I think a portable function like this could be easily added to C and it
would be used a lot considering how many people have asked for something
like this.
Nov 14 '05 #10
> I think a portable function like this could be easily added to C and
it
would be used a lot considering how many people have asked for something like this.


I usually add this myself, by allocating extra memory and placing a
small header before each memory chunk. The header has a field to store
the chunk size. I usually put debugging information in the header too
e.g. where and when the memory was allocated - invaluable for tracing
memory leaks!

Nov 14 '05 #11
"Servé La" <bl****@bestaatniet.nl> wrote:
"Andrey Tarasevich" <an**************@hotmail.com> schreef in bericht
news:10*************@news.supernews.com...
Firstly, C standard library does not provide user with any means to
access this information.
Secondly, memory allocation functions are not guaranteed to allocate
exactly the requested amount of memory. Successful allocation requiest
might allocate more memory than was actually requested, which is
perfectly legal in C.
I understand this of course, but still I'd like to know why a function like
memsize can't be introduced in the std library. Maybe more bytes are
allocated than requested, a program shouldn't invoke undefined behaviour
when those extra bytes are overwritten right.
I think a portable function like this could be easily added to C and it
would be used a lot considering how many people have asked for something
like this.


I guess it's not entirely clear if such a function could really be added
that easily. At least it would put another constraint on the implementors
of malloc() and friends which might have been a reason not to introduce
such a function (and many implementations where it's easy to introduce
already have such a function as an extension) - but that's probably better
asked in comp.std.c where the experts for these questions can be found.

I am also not convinced that it would reduce the number of questions
asked - they probably would be immediately replaced by questions like:
"Why does memsize() tell me the block is xyz bytes large when I only
asked for abc bytes?" where abc < xyz. I actually guess that most people
would like to have this functionality to be able to pass pointers to
functions without the need to also pass the size of what's pointed to.
But if that would be possible (by making the memsize() function not
return the real amount of allocated memory but the size requested
in the malloc() call) then this still wouldn't work for fixed sized
arrays - unless some size information is also stored with fixed sized
arrays that can be obtained using the same hypothetical memsize()
fucntion. I.e. it would only really make sense if you could do

void func( int *x );

int main( void ) {
int a[ 100 ], *b = malloc( 250 * sizeof *b );
func( a );
func( b );
return 0;
}

void func( int *x )
{
printf( "%lu\n", ( unsigned long ) ( memsize( x ) / sizeof *x ) );
}

But then the way fixed sized arrays are dealt with would have to be
changed fundamentally...

And, of course, the next logical step would be a malloc() variant with
type information of the allocated memory stored and another function
for determining this type with a "return value" that can be used in
casts or tested for etc., so that void pointers could be passed around
and type-agnostic functions can be written. But then you really would
make C a rather different language...

Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Nov 14 '05 #12
Servé La wrote:

"Andrey Tarasevich" <an**************@hotmail.com> schreef in bericht
news:10*************@news.supernews.com...
Firstly, C standard library does not provide user with any means to
access this information.
Secondly, memory allocation functions are not guaranteed to allocate
exactly the requested amount of memory. Successful allocation requiest
might allocate more memory than was actually requested, which is
perfectly legal in C.


I understand this of course,
but still I'd like to know why a function like
memsize can't be introduced in the std library. Maybe more bytes are
allocated than requested, a program shouldn't invoke
undefined behaviour
when those extra bytes are overwritten right.


The ordinary way to use memory is to allocate it deliberately,
rather than to check and see if any unused memory has been left around.
C code shouldn't be writing beyond the size of the target type.

--
pete
Nov 14 '05 #13
al******@hotmail.com wrote:
I think a portable function like this could be easily added to C and it
would be used a lot considering how many people have asked for something
like this.


I usually add this myself, by allocating extra memory and placing a
small header before each memory chunk. The header has a field to store
the chunk size.


Beware - it is not trivial to do this and still ensure that the address
following the header is properly aligned for all types; in fact, it is
AFAIK impossible to do so portably.

Richard
Nov 14 '05 #14
On Tue, 25 Jan 2005 18:42:10 -0800, Ben Pfaff
<bl*@cs.stanford.edu> wrote:
al******@hotmail.com writes:
Yeah there was a typo. Unfortunately you can't edit posts here.


Usenet has a `supersedes' feature that you could use.


However, most news servers I know of these days don't accept it, it's
too easily abused by attackers (cancels similarly). And once it's got
to a client it's unlikely that supersedes will do anything apart from
look like a new message...

Chris C
Nov 14 '05 #15


Richard Bos wrote:
al******@hotmail.com wrote:

I think a portable function like this could be easily added to C and it
would be used a lot considering how many people have asked for something
like this.


I usually add this myself, by allocating extra memory and placing a
small header before each memory chunk. The header has a field to store
the chunk size.

Beware - it is not trivial to do this and still ensure that the address
following the header is properly aligned for all types; in fact, it is
AFAIK impossible to do so portably.


Er, not so: You could allocate the double, triple, ... amount of the
memory and pass only the address of the last "element" (i.e. the one
with the right size towards the end of allocated memory). If the
overhead is large enough to store your "small header", maybe with a
safety "distance" from the data starting address, you can memcpy() the
header you created there and retrieve it from there via memcpy() to a
"small header" object. Usually, this will require the double amount of
requested memory and be quite inefficient. (Triple and so on only for
very small amounts of dynamically allocated memory).
The fun starts with realloc(); then, you can even decide to keep the
old overhead and realloc() the difference or whatever rocks your boat.

It's just not worth it :-)
Cheers
Michael
--
E-Mail: Mine is a gmx dot de address.

Nov 14 '05 #16
On Wed, 26 Jan 2005 18:18:57 +0100, Michael Mair wrote:


Richard Bos wrote:
al******@hotmail.com wrote:

I think a portable function like this could be easily added to C and it
would be used a lot considering how many people have asked for something
like this.

I usually add this myself, by allocating extra memory and placing a
small header before each memory chunk. The header has a field to store
the chunk size.

Beware - it is not trivial to do this and still ensure that the address
following the header is properly aligned for all types; in fact, it is
AFAIK impossible to do so portably.


Er, not so: You could allocate the double, triple, ... amount of the
memory and pass only the address of the last "element" (i.e. the one
with the right size towards the end of allocated memory).


Which one is that, how do you that whether it is properly aligned for
*any* C type?

Lawrence
Nov 14 '05 #17


Lawrence Kirby wrote:
On Wed, 26 Jan 2005 18:18:57 +0100, Michael Mair wrote:


Richard Bos wrote:
al******@hotmail.com wrote:

>I think a portable function like this could be easily added to C and it
>would be used a lot considering how many people have asked for something
>like this.

I usually add this myself, by allocating extra memory and placing a
small header before each memory chunk. The header has a field to store
the chunk size.
Beware - it is not trivial to do this and still ensure that the address
following the header is properly aligned for all types; in fact, it is
AFAIK impossible to do so portably.


Er, not so: You could allocate the double, triple, ... amount of the
memory and pass only the address of the last "element" (i.e. the one
with the right size towards the end of allocated memory).


Which one is that, how do you that whether it is properly aligned for
*any* C type?


Maybe there is an error in my train of thought, but I thought
about:
MALLOC_WRAPPER(size)
checking whether size is large enough for "small header+safety distance"
I assume it is, otherwise this goes with n*size/(n-1)*size:

So, I unsigned char *p=malloc(2*size), do all the checks and give the
user only the address q=p+size. If the user did give us the return value
of a sizeof Operation (or strlen() call) times something, we should
now have the proper alignment at q.
I enter all the values into a struct small_header object and memcpy() it
to a fixed negative offset with respect to q. I cannot access it there,
of course, but I can memcpy() it to a struct small_header variable and
work with that.

C89:
We run into problems as soon as the user is not honest with us because
(s)he allocates "too much". Example: struct hack.
Our memory alignment requirements may be violated.

C99:
Here, we obviously cannot cope with flexible array members for much
the same reasons (which is why there are no arrays of structures
with f.a.m.)

So, if used correctly and within these restrictions (and with an
overallocating solution for struct hack/f.a.m. working essentially
along the above lines but in the other direction), these should work.

Have I forgotten something? Probably yes :-)
Cheers
Michael
--
E-Mail: Mine is a gmx dot de address.

Nov 14 '05 #18
On Wed, 26 Jan 2005 19:00:38 +0100, Michael Mair
<Mi**********@invalid.invalid> wrote:
Maybe there is an error in my train of thought, but I thought
about:
MALLOC_WRAPPER(size)
checking whether size is large enough for "small header+safety distance"
I assume it is, otherwise this goes with n*size/(n-1)*size: [...] C89:
We run into problems as soon as the user is not honest with us because
(s)he allocates "too much". Example: struct hack.
Our memory alignment requirements may be violated.
That isn't dishonest, it's the only way to get a variable amount of
data. Indeed, you're doing a form of it yourself.
C99:
Here, we obviously cannot cope with flexible array members for much
the same reasons (which is why there are no arrays of structures
with f.a.m.)
For exactly the same reasons, it won't work, and this use is now blessed
by the Standard.
So, if used correctly and within these restrictions (and with an
overallocating solution for struct hack/f.a.m. working essentially
along the above lines but in the other direction), these should work.
If your restrictions are sufficient, yes, a non-general solution can be
made to work. Another is to use:

union AlignStuff
{
int i;
long l;
long long ll;
void *vp;
} AS[2];

and whatever other types you know your system uses, and use

ptrdiff_t align = (char*)AS[1] - (char*)AS[0];

(because that is guaranteed to give the distance between two objects
aligned for the worst case, so allocate space for your overhead in
n*align bytes). You can include in that all of the types you know your
program uses, but make sure that if other types are added they are
included in the union as well (for instance, a pointer to long or to a
function might be a different alignment from pointer to void).
Have I forgotten something? Probably yes :-)


As I said a few weeks back here, it is possible to make a general
allocator which isn't portable (because it knows about system details),
or a portable one which isn't general (because it doesn't know those
details), but not one which is both portable and general within the C
language (if you can run a program to get information from the system or
interactively when installing, for instance from the GNU autoconf
configure script, then you can make it portable and general -- as long
as your program or script is itself portable!).

Question:

In my suggestion above, is (char*)AS[1] - (char*)AS[0] guaranteed to
be the same as sizeof(AS[0])? Where?

Chris C
Nov 14 '05 #19
al******@hotmail.com wrote:
I usually add this myself, by allocating extra memory and placing a
small header before each memory chunk. The header has a field to store the chunk size. I usually put debugging information in the header too e.g. where and when the memory was allocated - invaluable for tracing
memory leaks!

FWIW I have used this technique for a couple of years on a number of
different architectures, including games consoles which have odd
alignment requirements. I usually make the header 256 bytes and I've
never had any problems.

For those that haven't already seen it, here's the code to pass the
allocation location into the allocation function:

void * DbgAlloc( size_t bytes, const char *file, int line );

#define MALLOC(X) DbgAlloc( bytes, __FILE__, __LINE__ )

It's a very useful technique which can easily be adapted for other
resources. The code's no doubt horribly non-standard compliant (like
most of the compilers I use) :)

Nov 14 '05 #20
Chris Croughton wrote:
Ben Pfaff <bl*@cs.stanford.edu> wrote:
al******@hotmail.com writes:
Yeah there was a typo. Unfortunately you can't edit posts here.


Usenet has a `supersedes' feature that you could use.


However, most news servers I know of these days don't accept it,
it's too easily abused by attackers (cancels similarly). And once
it's got to a client it's unlikely that supersedes will do anything
apart from look like a new message...


However, an adequate substitute is to gaze admiringly at your own
superb and intelligent reply, and generally drink in the subtleties
involved, before hitting that final 'send' key.

If you read and post offline you can even postpone this idolatrous
self-admiration session until just before going back on line. That
may give you a more encompassing view of the positive effects you
are bringing to the universe.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #21
Lawrence Kirby wrote:

On Wed, 26 Jan 2005 18:18:57 +0100, Michael Mair wrote:


Richard Bos wrote:
al******@hotmail.com wrote:
>I think a portable function like this could be easily added to C and it
>would be used a lot considering how many people have asked for something
>like this.

I usually add this myself, by allocating extra memory and placing a
small header before each memory chunk. The header has a field to store
the chunk size.
Beware - it is not trivial to do this and still ensure that the address
following the header is properly aligned for all types; in fact, it is
AFAIK impossible to do so portably.


Er, not so: You could allocate the double, triple, ... amount of the
memory and pass only the address of the last "element" (i.e. the one
with the right size towards the end of allocated memory).


Which one is that, how do you that whether it is properly aligned for
*any* C type?


The DS9 requires that all the log2(sizeof(type)) bits of the
address be 1 bits. This allows it to discard those bits in pointer
representations.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #22
Chris Croughton wrote:
On Wed, 26 Jan 2005 19:00:38 +0100, Michael Mair
<Mi**********@invalid.invalid> wrote:

Maybe there is an error in my train of thought, but I thought
about:
MALLOC_WRAPPER(size)
checking whether size is large enough for "small header+safety distance"
I assume it is, otherwise this goes with n*size/(n-1)*size:
[...]
C89:
We run into problems as soon as the user is not honest with us because
(s)he allocates "too much". Example: struct hack.
Our memory alignment requirements may be violated.


That isn't dishonest, it's the only way to get a variable amount of
data. Indeed, you're doing a form of it yourself.


Mmmh... The struct hack is non-conforming and works in the realm of
UB even though it seems to do the same thing everywhere.
However, nobody can disallow me to malloc(size + 23) whenever
I malloc something -- there goes the method.
What I am doing is mainly hoping that whatever is to be allocated
can be put into an array.
As I mentioned: If you make a special wrapper for struct hack/flexible
array member, you still can use this method.

C99:
Here, we obviously cannot cope with flexible array members for much
the same reasons (which is why there are no arrays of structures
with f.a.m.)


For exactly the same reasons, it won't work, and this use is now blessed
by the Standard.


Right. And by allocating too much memory (as we are already doing
so why bother with more waste?) we can still use the above approach.

So, if used correctly and within these restrictions (and with an
overallocating solution for struct hack/f.a.m. working essentially
along the above lines but in the other direction), these should work.


If your restrictions are sufficient, yes, a non-general solution can be
made to work. Another is to use:

union AlignStuff
{
int i;
long l;
long long ll;
void *vp;
} AS[2];

and whatever other types you know your system uses, and use

ptrdiff_t align = (char*)AS[1] - (char*)AS[0];

(because that is guaranteed to give the distance between two objects
aligned for the worst case, so allocate space for your overhead in
n*align bytes). You can include in that all of the types you know your
program uses, but make sure that if other types are added they are
included in the union as well (for instance, a pointer to long or to a
function might be a different alignment from pointer to void).


Hmmm, but this is still no "one size fits all" approach.
I do not like the waste of the other method but within its
restrictions, you can program it in a portable way.

Have I forgotten something? Probably yes :-)

As I said a few weeks back here, it is possible to make a general
allocator which isn't portable (because it knows about system details),
or a portable one which isn't general (because it doesn't know those
details), but not one which is both portable and general within the C
language (if you can run a program to get information from the system or
interactively when installing, for instance from the GNU autoconf
configure script, then you can make it portable and general -- as long
as your program or script is itself portable!).


Yep. But I was not looking for a general allocator.

BTW: You always can store the addresses allocated via malloc()
together with other information as requested size at the last
malloc()/realloc(). This of course gives you a non-constant
access time. The above approach is more or less just playing
around to find out inhowfar you can realise the "I store the
information just at a negative offset w.r.t beginning of
the storage area" :-)

Question:

In my suggestion above, is (char*)AS[1] - (char*)AS[0] guaranteed to
be the same as sizeof(AS[0])? Where?


I am not sure about using ptrdiff_t at all.

You probably look for

"6.5.3.4 The sizeof operator
[...]

3 [...]
When applied to an operand that has structure or union type, the result
is the total number of bytes in such an object, including internal and
trailing padding.
"

"6.7.2.1 Structure and union specifiers
[...]

14 The size of a union is sufficient to contain the largest of its
members. The value of at most one of the members can be stored in a
union object at any time. A pointer to a union object, suitably
converted, points to each of its members (or if a member is a bit-
field, then to the unit in which it resides), and vice versa.

15 There may be unnamed padding at the end of a structure or union.
"
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #23

"CBFalconer" <cb********@yahoo.com> wrote in message
news:41***************@yahoo.com...
However, an adequate substitute is to gaze admiringly at your own
superb and intelligent reply, and generally drink in the subtleties
involved, before hitting that final 'send' key.


I suppose actually *testing* the code first is out of the question?

Any code I haven't tried I'd mark as 'untested', which is OK if it's just to
convey an idea.

Bart
Nov 14 '05 #24
Michael Mair <Mi**********@invalid.invalid> wrote:
Richard Bos wrote:
al******@hotmail.com wrote:
I usually add this myself, by allocating extra memory and placing a
small header before each memory chunk. The header has a field to store
the chunk size.


Beware - it is not trivial to do this and still ensure that the address
following the header is properly aligned for all types; in fact, it is
AFAIK impossible to do so portably.


Er, not so: You could allocate the double, triple, ... amount of the
memory and pass only the address of the last "element" (i.e. the one
with the right size towards the end of allocated memory).


Take the following snippet:

int *ip;
char *cp;

ip=extra_malloc(sizeof *ip + sizeof char);
cp=ip + sizeof *ip;
*cp='a';
*ip=1438;

Now suppose sizeof(int) is 4, and ints must be properly aligned on
4-byte addresses. Had I used the normal, implementation-provided
malloc(), the above code would have been perfectly conforming. A little
odd, perhaps, but perfectly OK. malloc() returns a good, omni-aligned
pointer; ip is a valid, well-aligned int *; and cp, being a char *,
cannot be unaligned.
Ok, but now with the extra header. What I do is call extra_malloc(5).
extra_malloc, presumably, calls malloc(5). _This_ pointer is aligned for
everything, including an int. Now it adds 5 to that pointer. The result
is not properly int-aligned any more. Yet it gets passed out as if it's
a perfectly good pointer, and I assign it to an int *...

Richard
Nov 14 '05 #25
Bart C wrote:
Any code I haven't tried I'd mark as 'untested',
which is OK if it's just to convey an idea.


I don't see any point in marking code "untested".
All posted code is subject to review and
code marked "tested" has no real guarantee.

--
pete
Nov 14 '05 #26


Richard Bos wrote:
Michael Mair <Mi**********@invalid.invalid> wrote:

Richard Bos wrote:
al******@hotmail.com wrote:

I usually add this myself, by allocating extra memory and placing a
small header before each memory chunk. The header has a field to store
the chunk size.

Beware - it is not trivial to do this and still ensure that the address
following the header is properly aligned for all types; in fact, it is
AFAIK impossible to do so portably.


Er, not so: You could allocate the double, triple, ... amount of the
memory and pass only the address of the last "element" (i.e. the one
with the right size towards the end of allocated memory).

Take the following snippet:

int *ip;
char *cp;

ip=extra_malloc(sizeof *ip + sizeof char);
cp=ip + sizeof *ip;
*cp='a';
*ip=1438;

Now suppose sizeof(int) is 4, and ints must be properly aligned on
4-byte addresses. Had I used the normal, implementation-provided
malloc(), the above code would have been perfectly conforming. A little
odd, perhaps, but perfectly OK. malloc() returns a good, omni-aligned
pointer; ip is a valid, well-aligned int *; and cp, being a char *,
cannot be unaligned.
Ok, but now with the extra header. What I do is call extra_malloc(5).
extra_malloc, presumably, calls malloc(5). _This_ pointer is aligned for
everything, including an int. Now it adds 5 to that pointer. The result
is not properly int-aligned any more. Yet it gets passed out as if it's
a perfectly good pointer, and I assign it to an int *...


Which is the issue I already addressed in the other subthread.
It works only if the user gives me the size of an object which
can be an array member. However, with allocating more memory for
things like the struct hack (or flexible array members) by telling
the size of the original "array-able" type plus the required extra
memory, you could again "heal" it :-)

Just for the record: I think this is really a stupid way of doing
it but it is feasible and can be implemented in standard C.
Cheers
Michael
--
E-Mail: Mine is a gmx dot de address.

Nov 14 '05 #27
pete <pf*****@mindspring.com> writes:
I don't see any point in marking code "untested".
All posted code is subject to review and
code marked "tested" has no real guarantee.


I have certain standards for code that I post. Part of that
includes testing. At the very least, it will uncover typos,
omissions of headers, and so on. If I don't take the time that I
normally would to test code, I often mark it "untested" to warn
people. I don't see why this is a bad thing.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 14 '05 #28

In article <41***********************@news.xs4all.nl>, "Servé La" <bl****@bestaatniet.nl> writes:

I understand this of course, but still I'd like to know why a function like
memsize can't be introduced in the std library.


Here are some good reasons:

- There may be extant implementations where the *implementation* does
not, in fact, keep track of the size of the allocated area. The
implementation may be running in a hosted environment which itself
handles allocation, and malloc, calloc, realloc, and free might just
be wrappers. Your "memsize" could require a substantial and
infelicitous change to such an implementation.

- Either memsize must have defined behavior (whether explicit in the
standard or implementation-defined) for arguments which are not
pointers returned by malloc/calloc/realloc, or it must have undefined
behavior for them. The former would require implementations to be
able to identify pointers to allocated memory and distinguish them
from arbitrary values, which is unreasonable. The latter would
introduce a whole new class of nasty bugs. (Essentially these would
be the same bugs that already exist for free and realloc, but the
mooted memsize would be useful in many contexts where those two are
not, so it would likely be used incorrectly far more often.)

- If memsize always returns the requested size, the implementation now
has to keep track of two sizes: requested and actual.

- If memsize always returns the actual size, you've created potential
skew in the program logic. The allocating function may be written to
treat the maximum amount of data in the allocated area as the
requested size, while another function may use memsize (because,
presumably, the use of memsize is to avoid keeping track of the
requested size) and fill the area to its actual size. Return to the
allocating function and you have silent data truncation. It's easy
to see how this might happen, particularly in maintenance.

What it really comes down to for me, though, is that there few good
purposes served by "memsize" - far fewer than many people seem to
think. A program should keep track of the requested sizes of the
areas it allocates, and treat them as being no larger. Some have
suggested that memsize would be useful for a library which wants to
verify that a receiving area is sufficiently large, but that still
would require a valid pointer from the caller - and what if the
caller wants to use an auto or static array, or a pointer into the
middle of an allocated area, as the destination instead?

--
Michael Wojcik mi************@microfocus.com

Thanks for your prompt reply and thanks for your invitatin to your
paradise. Based on Buddihism transmigration, I realize you, European,
might be a philanthropist in previous life! -- supplied by Stacy Vickers
Nov 14 '05 #29
Ben Pfaff wrote:
pete <pf*****@mindspring.com> writes:

I don't see any point in marking code "untested".
All posted code is subject to review and
code marked "tested" has no real guarantee.

I have certain standards for code that I post. Part of that
includes testing. At the very least, it will uncover typos,
omissions of headers, and so on. If I don't take the time that I
normally would to test code, I often mark it "untested" to warn
people. I don't see why this is a bad thing.


There are several degrees of testing. When I post code here I do expect
comment. "This crap won't even compile!" is not what I want to hear.

Wrap your code example in a real program that demonstrates the point of
the code example. Test it to the point that it compiles cleanly and
makes your point. Post the whole program.

--
Joe Wright mailto:jo********@comcast.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #30
Michael Mair wrote:

Richard Bos wrote:
Michael Mair <Mi**********@invalid.invalid> wrote:
Richard Bos wrote:

al******@hotmail.com wrote:

> I usually add this myself, by allocating extra memory and placing a
> small header before each memory chunk. The header has a field to
> store
> the chunk size.
Beware - it is not trivial to do this and still ensure that the address
following the header is properly aligned for all types; in fact, it is
AFAIK impossible to do so portably.
Er, not so: You could allocate the double, triple, ... amount of the
memory and pass only the address of the last "element" (i.e. the one
with the right size towards the end of allocated memory).


Take the following snippet:

int *ip;
char *cp;

ip=extra_malloc(sizeof *ip + sizeof char);
cp=ip + sizeof *ip;
*cp='a';
*ip=1438;

Now suppose sizeof(int) is 4, and ints must be properly aligned on
4-byte addresses. Had I used the normal, implementation-provided
malloc(), the above code would have been perfectly conforming. A little
odd, perhaps, but perfectly OK. malloc() returns a good, omni-aligned
pointer; ip is a valid, well-aligned int *; and cp, being a char *,
cannot be unaligned.
Ok, but now with the extra header. What I do is call extra_malloc(5).
extra_malloc, presumably, calls malloc(5). _This_ pointer is aligned for
everything, including an int. Now it adds 5 to that pointer. The result
is not properly int-aligned any more. Yet it gets passed out as if it's
a perfectly good pointer, and I assign it to an int *...

Which is the issue I already addressed in the other subthread.
It works only if the user gives me the size of an object which
can be an array member. However, with allocating more memory for
things like the struct hack (or flexible array members) by telling
the size of the original "array-able" type plus the required extra
memory, you could again "heal" it :-)

Just for the record: I think this is really a stupid way of doing
it but it is feasible and can be implemented in standard C.


Just for the record: I still think that this is a really stupid way
to do it.

However, I took the liberty of implementing it:

http://kreativprojekt.gmxhome.de/dow.../overalloc.zip
(~6K, files are unix-like text files)

Compile with -DTEST/#define TEST for some basic tests.

Suggestions welcome. However, this is only a couple of hours'
work and certainly nothing with a well-thought-out interface.

Code with comments was too long to post here.
So, in the future, whenever someone asks for memsize(), you can
say "There is a really wasteful but standard conforming(*) way
of doing it; have a look at overalloc"
(*) If you use it correctly :-)
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #31
"CBFalconer" <cb********@yahoo.com> wrote in message
news:41***************@yahoo.com...
If you read and post offline...


What is this "offline"?

Is that like "offphone" or "offwater"? I had an "offelectric" episode
once, but we went "oncandle" to fix it.

I pray there will never be "offbeer"...!

--
Mabden
Nov 14 '05 #32
Ben Pfaff wrote:

pete <pf*****@mindspring.com> writes:
I don't see any point in marking code "untested".
All posted code is subject to review and
code marked "tested" has no real guarantee.


I have certain standards for code that I post. Part of that
includes testing. At the very least, it will uncover typos,
omissions of headers, and so on. If I don't take the time that I
normally would to test code, I often mark it "untested" to warn
people. I don't see why this is a bad thing.


It's not very bad, but it doesn't mean much to me.
It doesn't affect whether or not I will test your code.
It only affects my expectations when I test your code,
but I don't consider my expectations to be very important.

--
pete
Nov 14 '05 #33
pete <pf*****@mindspring.com> writes:
Ben Pfaff wrote:

pete <pf*****@mindspring.com> writes:
> I don't see any point in marking code "untested".
> All posted code is subject to review and
> code marked "tested" has no real guarantee.


I have certain standards for code that I post. Part of that
includes testing. At the very least, it will uncover typos,
omissions of headers, and so on. If I don't take the time that I
normally would to test code, I often mark it "untested" to warn
people. I don't see why this is a bad thing.


It's not very bad, but it doesn't mean much to me.
It doesn't affect whether or not I will test your code.
It only affects my expectations when I test your code,
but I don't consider my expectations to be very important.


Perhaps it is not important whether code I post is tested, if you
are the one reading it. Clearly, you have the knowledge needed
to evaluate my code on its own merits, regardless of what I say
about it. Statements about thoroughness of testing are not for
you. They are for the novices who frequent this newsgroup,
ill-equipped to evaluate the quality of responses to their
questions.
--
"What is appropriate for the master is not appropriate for the novice.
You must understand the Tao before transcending structure."
--The Tao of Programming
Nov 14 '05 #34
Ben Pfaff wrote:

pete <pf*****@mindspring.com> writes:
Ben Pfaff wrote:

pete <pf*****@mindspring.com> writes:

> I don't see any point in marking code "untested".
> All posted code is subject to review and
> code marked "tested" has no real guarantee.

I have certain standards for code that I post. Part of that
includes testing. At the very least, it will uncover typos,
omissions of headers, and so on. If I don't take the time that I
normally would to test code, I often mark it "untested" to warn
people. I don't see why this is a bad thing.


It's not very bad, but it doesn't mean much to me.
It doesn't affect whether or not I will test your code.
It only affects my expectations when I test your code,
but I don't consider my expectations to be very important.


Perhaps it is not important whether code I post is tested, if you
are the one reading it. Clearly, you have the knowledge needed
to evaluate my code on its own merits, regardless of what I say
about it. Statements about thoroughness of testing are not for
you. They are for the novices who frequent this newsgroup,
ill-equipped to evaluate the quality of responses to their
questions.


Thank you.

--
pete
Nov 14 '05 #35
On Thu, 27 Jan 2005 08:12:34 GMT, rl*@hoekstra-uitgeverij.nl (Richard
Bos) wrote:
<snip>
Take the following snippet:

int *ip;
char *cp;

ip=extra_malloc(sizeof *ip + sizeof char);
[snip: as an attempted substitute for malloc]
cp=ip + sizeof *ip;
FTR you meant (char*)ip + sizeof *ip
or (char*)(ip + 1) or (char*)&ip[1]
*cp='a';
*ip=1438;


- David.Thompson1 at worldnet.att.net
Nov 14 '05 #36

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

19 posts views Thread by Espen Ruud Schultz | last post: by
26 posts views Thread by junky_fellow | last post: by
6 posts views Thread by copx | last post: by
669 posts views Thread by Xah Lee | last post: by
232 posts views Thread by robert maas, see http://tinyurl.com/uh3t | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.