Questions about malloc()

D

Dave Vandervies

Joe Wright said:
Someone many years ago (who?) chose to implement malloc()/free() in
a truly minimalist fashion. Minimalism has a long and credible
history in C but I think malloc()/free() is poorly designed.

It would be trivial for malloc/realloc/calloc to 'remember' what
they do in a List so that free() can do the right thing.

[snip more thoughts]
This is usenet and anybody can respond with anything. I know that
well. But these are not idle ramblings. I have implemented all of
this here at home and it works perfectly. My question in all this is
"Why wasn't it done this way the first time?".

Most likely because it's easier to implement a non-minimalist solution
on top of a minimalist one when you need the extra functionality than to
implement a minimalist solution on top of a non-minimalist one when you
really do need minimalism (or want to work from a minimalist starting
point to construct a slightly different non-minimalist version).

You now have my_malloc, my_realloc, my_free, my_freeall, my_alloced_size,
and other assorted useful stuff. Go ahead and use them. It's what
you need, it will make you more effective, and other people who need a
slightly different non-minimal solution or who want to have a hosted
implementation for an 8-bit processor still have the minimal ones to
work from.

If you feel like going over to The Dark Side, you can even put them
in a different namespace than the standard library versions, give them
the same names, and use `using' to let you use the unqualified names.
But that's off-topic here.


dave

--
Dave Vandervies (e-mail address removed)
I'm afraid that Comeau/Dinkum aren't going to get rich fast because they
sell the only C99 implementation available now. --Dan Pop and
We'll settle for getting rich slowly. P.J. Plaugher in comp.lang.c
 
D

Dan Pop

In said:
For this sort of reason, I do not mind:

free(ptr), ptr = NULL;

but in many cases it does not really add much to debuggability.
It *does* help if (but only if) you can establish an invariant:
"ptr is either NULL, or a valid pointer" -- and that depends greatly
on the context in which "ptr" appears.

To expand a bit on your point: the above construct, which can be trivially
automated with a macro wrapper for free() is useless when you have other
pointers pointing in the block being deallocated. If you don't nullify
*all* of them right after (or before) calling free(), nullifying only one
of them is not going to buy you much.

Dan
 
H

Herbert Rosenau

It would be trivial for malloc/realloc/calloc to 'remember' what
they do in a List so that free() can do the right thing. If we call
free() with a 'wild' pointer the system would look it up in the List
and, not finding it, do nothing.

When you needs nappies you should avoid using C. Use Cobol instead.
The List might also remember the size of the allocation and so
permit the much wanted 'size_t size(void *m);' which would return
the amount of memory allocated at a particular address, or zero if
we can't find m in the List.

When you needs a pair of braces beside belt or nappies don't program
in C. There are programming languages enough aroud you gets double and
tripel boundles of braces, belts with nappies but C is designed to
give the best in performance and throughput - but requires that you
have a brain to think yourself.
Also, because the List remembers ALL *alloc() calls, we can support
yet another function, freeall(), which will free all allocated memory.

There is nothing that requires that C dos a bit for you, replacing
your brain. Use your brain and you gets what you needs.
This is usenet and anybody can respond with anything. I know that
well. But these are not idle ramblings. I have implemented all of
this here at home and it works perfectly. My question in all this is
"Why wasn't it done this way the first time?".
Don't ask C to be your nourse, nammy, grandma or mom - it will not
work for you. C will require that you have a functional brain and able
to use it. When you're unable to follow this you should avoid
programming in C and use another language.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
C

Chris Croughton

Someone many years ago (who?) chose to implement malloc()/free() in
a truly minimalist fashion. Minimalism has a long and credible
history in C but I think malloc()/free() is poorly designed.

It is? They seem to have worked fine for many years.
It would be trivial for malloc/realloc/calloc to 'remember' what
they do in a List so that free() can do the right thing. If we call
free() with a 'wild' pointer the system would look it up in the List
and, not finding it, do nothing.

No, it is not 'trivial'. It takes up extra memory (which was a big
factor when the C library was originally designed) to keep the list,
and searching through the list each time can take a lot of time (many
programs have thousands of allocated blocks). Imposing that on all
programs via the standard would be disastrous. A program with a large
database could have a million blocks allocated, if free() checked each
one against the list every call it would take a sizeable fraction of a
second each time, and the overhead of the link pointers would be several
megabytes (quite possibly more if the alignment size is large).
The List might also remember the size of the allocation and so
permit the much wanted 'size_t size(void *m);' which would return
the amount of memory allocated at a particular address, or zero if
we can't find m in the List.

Again, it is neither necessary nor desirable for most real programs,
which know (if they need to) how big the allocated memory is and whether
it has been allocated or assigned (and they do reference counting or
whatever as needed).
Also, because the List remembers ALL *alloc() calls, we can support
yet another function, freeall(), which will free all allocated memory.

Exit from the program, that will do it on most systems. Depending what
you mean by 'all' allocated memory -- that allocated in your program, in
the current thread, in the the whole system?

What you suggest might have some value in a teaching or debugging
environment, to catch errors, and indeed there are a number of wrapper
functions to do just that (dmalloc, for instance). They can also do
things like putting 'guard' areas round the allocated memory to catch
writes to adjacent unallocated memory (in particular "off by one"
errors). However, in production code the size and speed hit is
non-trivial and unwanted.

But teaching people that memory is always protected against multiple
uses of free() on the same address is dangerous. Teaching them
defensive programming (check things yourself) in the first place is much
more valuable.
This is usenet and anybody can respond with anything. I know that
well. But these are not idle ramblings. I have implemented all of
this here at home and it works perfectly. My question in all this is
"Why wasn't it done this way the first time?".

Because most real programmers neither need nor want it. They design
properly so that there aren't memory 'leaks' or attempts to free memory
more than once, and they build in tests for things which might go wrong
(and use things like dmalloc during testing to make sure that they
haven't missed something).

If you want something which holds your hand, you write it (as you say
you have done), or find someone else's wrapper functions to do it. That
way you are in control of what your program does, and can make
appropriate tradeoffs.

One of my recent applications, in fact, does exactly that. I have a
need to allocate a lot of small areas (often inefficient with the system
malloc and free), and to go through allocating a lot of storage which I
then want to get rid of en masse before the next cycle (while leaving
some other allocated memory intact, which your 'freeall' wouldn't do).
I therefore have wrappers round the malloc functions to allocate what I
need in the way that I need it and to track it. Your functions wouldn't
help, though, I'd still have to code round them and the efficiency would
drop accordingly.

Chris C
 
J

Joe Wright

Herbert said:
When you needs nappies you should avoid using C. Use Cobol instead.




When you needs a pair of braces beside belt or nappies don't program
in C. There are programming languages enough aroud you gets double and
tripel boundles of braces, belts with nappies but C is designed to
give the best in performance and throughput - but requires that you
have a brain to think yourself.




There is nothing that requires that C dos a bit for you, replacing
your brain. Use your brain and you gets what you needs.



Don't ask C to be your nourse, nammy, grandma or mom - it will not
work for you. C will require that you have a functional brain and able
to use it. When you're unable to follow this you should avoid
programming in C and use another language.

Rosenau, where does this come from? My comments re *alloc/free were
technical and well presented (If I say so myself). Your response
does not treat any technical issue raised but only insults me
personally. Was this your intent?
 
G

Gordon Burditt

Someone many years ago (who?) chose to implement malloc()/free() in
a truly minimalist fashion. Minimalism has a long and credible
history in C but I think malloc()/free() is poorly designed.

It would be trivial for malloc/realloc/calloc to 'remember' what
they do in a List so that free() can do the right thing.

It may not be trivial in terms of run-time efficiency and paging
behavior .
If we call
free() with a 'wild' pointer the system would look it up in the List
and, not finding it, do nothing.

I believe the RIGHT THING here would be to call abort(). Stomp the
bugs, don't paper over them, and don't just occasionally fail.
The List might also remember the size of the allocation and so
permit the much wanted 'size_t size(void *m);' which would return
the amount of memory allocated at a particular address, or zero if
we can't find m in the List.

And what happens if the size of the allocation turns out to be not
what was originally requested? Does the (programmer-written) program
freak out? This can legitimately happen for such reasons as rounding
the request up to the next multiple of alignment restrictions.
Also, because the List remembers ALL *alloc() calls, we can support
yet another function, freeall(), which will free all allocated memory.

Of what possible use is such a function? You want to yank file
buffers out from under files you fopen()ed? You want to clobber
all the memory allocated by a third-party library you use? Is there
anything in ANSI C that says that the strings pointed to by argv[]
AREN'T allocated by malloc() before main() is started?

I could see where this could be useful if you can allocate memory
from a "pool" (which only the creator and those functions the creator
passes the pool handle to can allocate from) and you can release all
memory allocated from that pool. It is not useful when you have
to keep track of memory allocated by ANY function.
This is usenet and anybody can respond with anything. I know that
well. But these are not idle ramblings. I have implemented all of
this here at home and it works perfectly. My question in all this is
"Why wasn't it done this way the first time?".

Gordon L. Burditt
 
H

Herbert Rosenau

Rosenau, where does this come from? My comments re *alloc/free were
technical and well presented (If I say so myself). Your response
does not treat any technical issue raised but only insults me
personally. Was this your intent?

You were asking for nappies - repeated quote:

C is dersigned to avoid anything an halfway experienced programmer
knows himself. That is
- knowing what C objects he had requested from the runtime - no need
for C to bookeeping the bookkeeping for nappiy wearer. But heping the
experienced programmer of time critical services. Superflous checking
costs even in an 10ThZ environment too much time, given better to real
needed work.

Write a program that loops 1,000,000,000 times over the same code but
with constant changing data, needing 10 malloc(), 5 - 10 free() each
round. Test on each case where it is absolutely clear that a pointer
needs to give back its value it points to that it contains a guilty
pointer. Do the same without the check - and you sees the difference.

That is why you needs to be adult in C not a baby. You have to learn
what C is and how it is designed to give you the chance to save
exactly the 10ms you needs to get your program excactly the point it
needs.

YOU would set your pointer to NULL when you gives its value back AND
it will not loose its visibility without return immediately. You would
save this action when you knows it looses its vilibility without
return. You would have on another places to initialise the pointer to
NULL because you would know that you later would NOT know if or if not
the pointer is valid.

It is on YOU to know when a pointer contains a valid data - or when
not. Assigning a null pointer constant to it will simply help you to
remember its state - when needed.

1 ms runtime saved can be critical to get the job done or failing on
it. It is the job of C to support you as possible in that. It is NOT
the job of C to supporty you in carrying nappies. For that you have
lots over lots on debugging methods - and assigning null pointer
constants is one of the primitivest ones. YOU would avoid it when you
knows what you does - and you would do it right and anyway better than
free() will ever be able to.

C is designed as an assembler for an abstract mashine - giving the
compiler all any any possibilities to make the best out of it on a
real mashine. That is the runtime will be optimised (by compiler
and/or by hand to get the best out of the real mashine. Inserting
probes of probes who are clearly most often nothing than more than
superflous hinders experienced programmers to get the same level out
on theyr own code because there are nappy bearer who are unable to
think theyrself.

Learn how to use pointers, learn how to handle them and you would know
better than the malloc family can ever know about them.

It is on YOU to learn how to call free() with pointers already
free()d, it is on you to know how to call realloc() without knowing
exactly that you have a pointer to a memory area allowed for
m/c/realloc/free. It IS so easy to control that there is nothing
needed as the brain of the programmer using them. It is not hard to
learn the technology needed:

1. initialise each and any pointer you have no real value for yet with
a null pointer constant.
2. reset each pointer that gets alive more than 3 statements after
free() to hold a null pointer constant instead of its original.
3. do never free() a memory area whereas some pointers to outside
direct access yet.

Easy, eh?


--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
D

Dave Vandervies

You were asking for nappies - repeated quote:

No, he was asking for a potentially useful feature.

There are enough good reasons to not include this particular potentially
useful feature; giving those reasons would've been rather more helpful
than abuse.
(Not that abuse is ever a useful reply.)


That is why you needs to be adult in C not a baby. You have to learn
what C is and how it is designed to give you the chance to save
exactly the 10ms you needs to get your program excactly the point it
needs.

So we can safely assume that you don't use anything in <string.h>, and
nothing from <stdio.h> except fopen/fclose/fputc/fgetc, or anything in
<math.h>, or...?

After all, doing all the work yourself will let you design somethign
that can give you the chance to save another 10ms.

For that matter, why bother with C at all? Real Men write in assembly...


dave
(Don't go away mad, just go away.)
 
K

Keith Thompson

Herbert Rosenau said:
Learn how to use pointers, learn how to handle them and you would know
better than the malloc family can ever know about them.

It is on YOU to learn how to call free() with pointers already
free()d, it is on you to know how to call realloc() without knowing
exactly that you have a pointer to a memory area allowed for
m/c/realloc/free. It IS so easy to control that there is nothing
needed as the brain of the programmer using them. It is not hard to
learn the technology needed:

1. initialise each and any pointer you have no real value for yet with
a null pointer constant.
2. reset each pointer that gets alive more than 3 statements after
free() to hold a null pointer constant instead of its original.
3. do never free() a memory area whereas some pointers to outside
direct access yet.

Easy, eh?

Sure, it's easy. So easy that everybody gets it right, and C programs
don't suffer from wild pointers or buffer overruns, and viruses don't
propagate.

There are arguments to be made in favor of the C approach. The valid
ones don't include the words "nappy" and "baby".
 
H

Herbert Rosenau

So we can safely assume that you don't use anything in <string.h>, and
nothing from <stdio.h> except fopen/fclose/fputc/fgetc, or anything in
<math.h>, or...?

No, you can't. Yes, sometimes I avoid fgets, fscanf because fgetc
gives me more control over the input stream. The time handling puch
cards is gone away. I've really seldom the need to include math.h
because business applications and floatingpoint are incompatible at
all.
After all, doing all the work yourself will let you design somethign
that can give you the chance to save another 10ms.

For that matter, why bother with C at all? Real Men write in assembly...

Yeah, you're right - but C _is_ an assembler - for an abstract
mashine. A C compiler younger than 10 years will build better mashine
code than 80% of human programmers are able to and will not more bad
than the remaining 20%.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
D

Dave Vandervies

No, you can't.

And how are any of these any different from wrappers around malloc
and friends?

They're only there to keep track of things so you don't have to.


dave
 
K

Keith Thompson

Herbert Rosenau said:
[...]
For that matter, why bother with C at all? Real Men write in assembly...

Yeah, you're right - but C _is_ an assembler - for an abstract
mashine.

No, C isn't an assembler. The language has features that no assembly
language worthy of the name would have (arbitrarily complex
expressions, control flow constructs, etc.). It doesn't allow direct
access to CPU registers (the "register" keyword notwithstanding).
There's no direct mapping between any C construct and machine
instructions.

C is a relatively low-level language; it's semantically closer to
assembly than, say, Pascal or Ada. But saying that C is an assembly
language ignores the meaning of the term.
A C compiler younger than 10 years will build better mashine code
than 80% of human programmers are able to and will not more bad than
the remaining 20%.

That's true of just about any language whose compiler generates
machine code.
 
F

Flash Gordon

Yeah, you're right - but C _is_ an assembler - for an abstract
mashine. A C compiler younger than 10 years will build better mashine
code than 80% of human programmers are able to

Possibly true. My experience from back then is that the C compiler will
beet a lot of people who write assember.
and will not more bad
than the remaining 20%.

Definitely NOT always true. On one system I worked on in about '95 I had
to code some specific areas in assembler because the C code was proved
to be too slow. It was not even a marginal thing, the C code was far too
slow and my hand crafted assembler had (from memory) something like half
the time spare.
 
H

Herbert Rosenau

And how are any of these any different from wrappers around malloc
and friends?

They're only there to keep track of things so you don't have to.

What keeps track of what things? fgets()/fscanf()? Sometimes awkward
to get really conrolled what you need. O.k., read an punch card would
be easy - but is stdin always only a punch card? I don't think so.

Print out a long as 134,54 EUR - please use fprintf to do it - but be
sure you gets 0,45 and -1.234,45 even as -0,45. Yes, long, not double
- you knows business math is highly different from university math.
German uses ',' instead '.' and '.' instead ','. Sometimes most of
stdio.h is absolutely useless - even as it is sometimes powerfull.

The malloc family is designed well as it does the minimum needed in
any case - but nothing more. There is no need to give it more power -
because too often there is nothing to do as to free() memory a pointer
points to - because immediately thereafter the pointer will loose its
life itself or at least its visibility. Initialising variables (not
only pointers) is failsave programming. You'll learn that quickly when
your job is not only to produce M$ GUI code but human life hangs on
the code you writes. You gets stinking when you sees that the compiler
and runtime you uses is wasting CPU cycles and you have no chance to
get out to native assembly because you needs the portability C
delivers.

stdio was designed to handle punch cards but not keyboard, big files,
screens and other devices - so it works well when you can reduce the
i/o to look as if it were on punch cards - but gets problematic when
not.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
H

Herbert Rosenau

Herbert Rosenau said:
[...]
For that matter, why bother with C at all? Real Men write in assembly...

Yeah, you're right - but C _is_ an assembler - for an abstract
mashine.

No, C isn't an assembler. The language has features that no assembly
language worthy of the name would have (arbitrarily complex
expressions, control flow constructs, etc.). It doesn't allow direct
access to CPU registers (the "register" keyword notwithstanding).
There's no direct mapping between any C construct and machine
instructions.

Not true! I had used for about 5 years an macro assembler that had
limited types like C with int/unsigned int, char, float, double....,
using more complex experssions like store name(r5++) + (r4--) * mwst /
discount.
in C. name[ix] += *p5 * mwst / dicount;

Only a little bit difference in syntax. Controlflow constructs like
cmp arr(r6+7), arr2(r4-3)
bnzc (r1+947) # if (arr[i+7] != arr2[j-3]) {....}
repnzc g4, l4 # do { ...} while (x--);
repnz (var), 9444 # while (*var--) { .... }

No direct mapping?

r2 := dest,0 # r2 = wordaddress of dest, r3 byte no. start
r4 := src,0
r3 := fz r4, 0 # strlen(src)
r5 := r3 # copy number of bytes to dest
(r2++) :y (r4++) # memcpy(dest, src, strlen(src));
# or while (*src) *dest++ = *src++;
# or for (s = src, d = dwest, l = strlen(s);
l; l--) *d++ = *s++;

r5 := $BIBEAS("/bib/sub/file.txt", "OPEN READ");
bz error
r4 := $BIBEAS(r5, "READ", 2048, buf);
r3 := $BIBEAS(r5, "CLOSE");
whereas the OS itself had only knowledge of flat files, but a library
was able to handle subdirectories of 8 levels and the macro assember
was able to simplyfy the access to that

Depending on the hardware an assembler can be powerful.

We had used C on that mashine only because we would have portability.
C was at least not so useful as planned - but only because the
compiler was one of the most buggiest programs I've ever seen - and
the customer we're working for had delayed the holding of it until it
was too late to get the developer in regress and then unwilling to pay
the extra cost to get it right.
C is a relatively low-level language; it's semantically closer to
assembly than, say, Pascal or Ada. But saying that C is an assembly
language ignores the meaning of the term.

No, it describes exactly the idea of C. C is an assembler of an
abstact mashine. Look at the standard. It describes the behavior of
that abstract mashine exactly, like a hardware manual of an real
computer would describe that.

Pascal is designed to be a learning language even as it had found its
entry into the world of high level languages. ADA is designed as HLL,
but C is simply an portable assembler. Yes, with C89 and a bit more
with C99/98 it got a bit more of HLL - but its design is at least only
assemler of an well defined abstract mashine.
That's true of just about any language whose compiler generates
machine code.

No. It's relatvely easy to hit out any other language at assembly
level in code and performance when youre an good assembler programmer.
Each of them has its own strength - but they are not designed to beat
assembly programmers but to shorten developement time for theyr
special fields - and in that they are powerfull.

C is designed to beat assembly programmers, to shorten development
time in assembly developement, to shorten runtime and/or resource
usage whenever possible and to increase portability. Fortran is
designed to develop mathematical solutions, Cobol for business
solutions,....
I've used C compilers who were absolutely unable to generate mashine
code - but generates assembly. I've used C compilers who were unable
to generate mashine code or assembly but only P-code - whereas the
p-code was the same the assembler of that mashine was generating as
immediate step. It was the job of the linker to eat p-code and to
generate binary code ready for the system loader.



--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
H

Herbert Rosenau

Possibly true. My experience from back then is that the C compiler will
beet a lot of people who write assember.


Definitely NOT always true. On one system I worked on in about '95 I had
to code some specific areas in assembler because the C code was proved
to be too slow. It was not even a marginal thing, the C code was far too
slow and my hand crafted assembler had (from memory) something like half
the time spare.

Do you have time problems? Simply check the algorithm you use. I had
incresed throughput of hand crafted assembly by 2000%. I'd reduced its
memory usage from 400KB to 2KB by that. The algorithm the old code was
using was not too bad but bad enough to use more memory mor CPU cycles
than the buggy C compiler was producing using another one.

Find a better algorithm instead to try to write thae same in assembly.
Changing it to another brings lots more than to try to optimise per
hand what a halfways good compiler can do better.

I would say hand optimise already hand optimised braind dead code
increased the thoughput more than you can win by write something in
assembly than in C.

In 1980 it was easy for an really experienced assember programmer to
beat a C compiler. In 1990 it was hard, in 2000 it was nearly
impossible and in 2005 it would be impossible.

Use the right algorithm and the compiler will beat you. The only point
where you may need native assembly is:
- direct hardware access

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
F

Flash Gordon

Do you have time problems? Simply check the algorithm you use.

You are assuming that this had not already been done. In fact, I always
start by trying to device the most efficient algorithm.
I had
incresed throughput of hand crafted assembly by 2000%. I'd reduced its
memory usage from 400KB to 2KB by that. The algorithm the old code was
using was not too bad but bad enough to use more memory mor CPU cycles
than the buggy C compiler was producing using another one.

So you were dealing with either badly crafted assembler or a stupid
algorithm. That does not meen that other people are.
Find a better algorithm instead to try to write thae same in assembly.

That assumes you have not already optimised the algorithm.
Changing it to another brings lots more than to try to optimise per
hand what a halfways good compiler can do better.

Unless the compiler is allowed to use instructions the assembler
programmer is not it is IMPOSSIBLE for a compiler to produce better code
that could be produced by a sufficiently skilled assembler programmer.
After all, it is possible (not necessarily probable, unless said
programmer also writes compilers) for an assember programmer to produce
exactly the same code as the compiler.
I would say hand optimise already hand optimised braind dead code
increased the thoughput more than you can win by write something in
assembly than in C.

In 1980 it was easy for an really experienced assember programmer to
beat a C compiler. In 1990 it was hard, in 2000 it was nearly
^^^^ ^^^^^^
impossible and in 2005 it would be impossible.

So above you accept that within the time frame being reffered to, i.e.
within the last 10 years, it IS possible to beet the compiler. I
reffered to a specific example in about '95 where my assember skill were
sufficiently good to completely thrash the performance of the compiler.
This was having started with algorithm development and design aimed at
producing the most efficient code.
Use the right algorithm and the compiler will beat you.

Definitely not guaranteed. It is possible to produce by hand any code
that the compiler can produce. Further, since no SW is perfect it
follows that no compiler is perfect therefor there WILL be instances
where the compiler produces less than optimal code.
The only point
where you may need native assembly is:
- direct hardware access

The times when assembler is needed are reducing, both because of better
compilers and faster hardware, but there will always be areas where
compilers can be beeten, and sometimes by a long way. It's just not
often worth the effort required to beet them.

BTW, the only non-standard feature used in the original C implementation
was mapping a 2D array to a specific memory address, and that was done
with the linker.
 
G

glen herrmannsfeldt

Flash Gordon wrote:

(snip)
Unless the compiler is allowed to use instructions the assembler
programmer is not it is IMPOSSIBLE for a compiler to produce better code
that could be produced by a sufficiently skilled assembler programmer.
After all, it is possible (not necessarily probable, unless said
programmer also writes compilers) for an assember programmer to produce
exactly the same code as the compiler.

(snip)

For a sufficiently small piece of code I could probably agree.
That size might be about 10 lines of C. Past that, the
combinatorics are so bad that the assembly programmer would
never finish. A compiler using a dynamic programming algorithm
can find an optimal path through a long series of operation
extremely fast.

The advantage the assembly programmer has is knowing the
actual cases that are important, and may be able to make
optimizations that a compiler can't. Just one example.

A program may need to multiply two N bit integers generating
a 2N bit product. In C this must be done by multiplying two
2N bit numbers, yet the hardware might have an instruction
that can multiply N bit numbers with a 2N bit product.
It is possible the compiler will figure this out, but it
is likely that it won't.

Some machines have some special instructions that are
not normally used by compilers. It might be that they
are not useful in the general case, but are in a
specific case.

-- glen
 
J

Joona I Palaste

Yea, I suppose not. It could return a NULL:
p = free(p);
I just think free()'ing p and setting p = 0 should be handled in one step
since the operations are closely related and it avoids programmer error.

AFAIK free()ing a properly allocated pointer always succeeds, and
free()ing a pointer that has not been properly allocated always causes
undefined behaviour. So unless free() can distinguish between properly
allocated and not properly allocated pointers, the above definition
would define it as always returning NULL. What's the point of defining
a return value that is always going to be the same? Why not simply set
p to NULL yourself, because you know the correct value to set it to is
always NULL?
 
J

Jarno A Wuolijoki

What's the point of defining
a return value that is always going to be the same? Why not simply set
p to NULL yourself, because you know the correct value to set it to is
always NULL?

Well, it's about as pointless as returning a value that's always going to
be the same as one of the parameters..
 

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

Similar Threads

Alternative to Malloc in C 0
Malloc Query 86
Correct use of malloc 9
malloc and maximum size 56
malloc 40
array-size/malloc limit and strlen() failure 26
Malloc question 9
Malloc Query 8

Members online

No members online now.

Forum statistics

Threads
474,156
Messages
2,570,878
Members
47,404
Latest member
PerryRutt

Latest Threads

Top