By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,852 Members | 2,240 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,852 IT Pros & Developers. It's quick & easy.

Using malloc in C++?

P: n/a
I have read in Bjarne Stroustrup that using malloc and free should be
avoided in C++ because they deal with uninitialized memory and one
should instead use new and delete.

But why is that a problem? I cannot see why using malloc instead of new
does not give the same result.
Jun 7 '07 #1
Share this Question
Share on Google+
71 Replies


P: n/a
"desktop" <ff*@sss.comwrote in message
news:f4**********@news.net.uni-c.dk...
>I have read in Bjarne Stroustrup that using malloc and free should be
avoided in C++ because they deal with uninitialized memory and one should
instead use new and delete.

But why is that a problem? I cannot see why using malloc instead of new
does not give the same result.
(Untested code)

class Foo
{
int MyInt;
std::string MyString;
};

int main()
{
Foo* Bar = new Foo;
Foo* Screwed = malloc( sizeof( Foo ) );
}

New will call the constructor for the std::string. malloc won't.
Jun 7 '07 #2

P: n/a

desktop wrote:
I have read in Bjarne Stroustrup that using malloc and free should be
avoided in C++ because they deal with uninitialized memory and one
should instead use new and delete.

But why is that a problem?
The problem comes when you deal with object allocation, in C++, where
new not only allocates memory but also takes the constructor in hand.
>I cannot see why using malloc instead of new
does not give the same result.
For better understanding go through this link :
http://wiki.answers.com/Q/What_is_th...er_than_syntax
Regards,
ar

"There are things known and things unknown, in between are The Doors."

Jun 7 '07 #3

P: n/a
desktop wrote:
I have read in Bjarne Stroustrup that using malloc and free should be
avoided in C++ because they deal with uninitialized memory and one
should instead use new and delete.

But why is that a problem? I cannot see why using malloc instead of new
does not give the same result.
For a bucket of bytes or a C style struct, using malloc/free or
new/delete makes little or no difference. For objects with constructors
and/or destructors you have to use new/delete, so you may as well use
the same for all allocations.

--
Ian Collins.
Jun 7 '07 #4

P: n/a
desktop <ff*@sss.comschrieb:
I have read in Bjarne Stroustrup that using malloc and free should
be avoided in C++ because they deal with uninitialized memory and
one should instead use new and delete.

But why is that a problem? I cannot see why using malloc instead of
new does not give the same result.
This is a minor problem. The memory returned by new is also
uninitialized in a lot of cases.

Sure, new calls constructors and delete calls destructors while malloc
and free do not.

But there's another major reason for using new and delete: they are
much more portable while malloc/calloc/alloca/realloc/... are not. You
will normally never get a problem using new and delete, also on
different plattforms with different processors, because they
encapsulate all calls to the native malloc functions safely. These
operators belong to the language itself, not to the runtime library.
So you will normally not find includes of different headers and calls
to different allocation functions (both handled by conditional
compilation) and complicated casts for heap objects in strict C++
programs.

T.M.
Jun 7 '07 #5

P: n/a
Jim Langston wrote:
....
class Foo
{
int MyInt;
std::string MyString;
};

int main()
{
Foo* Bar = new Foo;
Foo* Screwed = malloc( sizeof( Foo ) );
}

New will call the constructor for the std::string. malloc won't.
MyInt is still not initialized tho.
Jun 7 '07 #6

P: n/a
Torsten Mueller wrote:
desktop <ff*@sss.comschrieb:
>I have read in Bjarne Stroustrup that using malloc and free should
be avoided in C++ because they deal with uninitialized memory and
one should instead use new and delete.

But why is that a problem? I cannot see why using malloc instead of
new does not give the same result.

But there's another major reason for using new and delete: they are
much more portable while malloc/calloc/alloca/realloc/... are not. You
will normally never get a problem using new and delete, also on
different plattforms with different processors, because they
encapsulate all calls to the native malloc functions safely. These
operators belong to the language itself, not to the runtime library.
So you will normally not find includes of different headers and calls
to different allocation functions (both handled by conditional
compilation) and complicated casts for heap objects in strict C++
programs.
I don't follow that paragraph, what isn't portable about the malloc
family of standard library functions?

--
Ian Collins.
Jun 7 '07 #7

P: n/a
Ian Collins wrote:
....
I don't follow that paragraph, what isn't portable about the malloc
family of standard library functions?
I don't know if they have been fixed but the following usually caused
problems with different behaviour on different platforms.

free(0)
malloc(0)
Jun 7 '07 #8

P: n/a
Gianni Mariani wrote:
Ian Collins wrote:
....
>I don't follow that paragraph, what isn't portable about the malloc
family of standard library functions?

I don't know if they have been fixed but the following usually caused
problems with different behaviour on different platforms.

free(0)
Specified as a NOP.
malloc(0)
Specified as far as you will either get a pointer to a block of >0 bytes
or NULL, just like any other size.

--
Ian Collins.
Jun 7 '07 #9

P: n/a
Ian Collins wrote:
....
>
>malloc(0)

Specified as far as you will either get a pointer to a block of >0 bytes
or NULL, just like any other size.
That would be a problem then.
Jun 7 '07 #10

P: n/a
Gianni Mariani wrote:
Ian Collins wrote:
....
>>
>>malloc(0)

Specified as far as you will either get a pointer to a block of >0 bytes
or NULL, just like any other size.

That would be a problem then.

Why? What ever you get from malloc, you can pass to free.

--
Ian Collins.
Jun 7 '07 #11

P: n/a
Ian Collins wrote:
Gianni Mariani wrote:
>Ian Collins wrote:
....
>>>malloc(0)
Specified as far as you will either get a pointer to a block of >0 bytes
or NULL, just like any other size.
That would be a problem then.

Why? What ever you get from malloc, you can pass to free.
Different behaviour on different systems. If I write code that assumes
malloc(0) returns unique values and it returns 0 on some, it will break.

I'm not sure if that's the only one but it is a source of inconsistency
between platforms.
Jun 7 '07 #12

P: n/a
Jim Langston wrote:
"desktop" <ff*@sss.comwrote in message
news:f4**********@news.net.uni-c.dk...
>>I have read in Bjarne Stroustrup that using malloc and free should be
avoided in C++ because they deal with uninitialized memory and one should
instead use new and delete.

But why is that a problem? I cannot see why using malloc instead of new
does not give the same result.

(Untested code)

class Foo
{
int MyInt;
std::string MyString;
};

int main()
{
Foo* Bar = new Foo;
Foo* Screwed = malloc( sizeof( Foo ) );
}
I know the code is untested but for the OP I will add that another problem I
have with malloc vs new is that malloc requires casting. You see in C++ you
don't have the C feature of void* implicitely casts to any* (only the
reverse still exists). Thus the code above doesn't compile and to make it
compile you actually need to make something like
Foo* Screwed = static_cast<Foo*>(malloc(sizeof(Foo)));

Clearly this is painful so better use "new". Not to mention malloc is error
prone because you may mistake the size of allocated memory (especially when
working on some other's people code) and you may allocate for another size
than the one for the type you need. While with new you have the "syntax
sugar" to just say I want an object of type T and everything is done
automatically (allocated memory to hold a sizeof(T), and returns a
converted T*).

--
Dizzy

Jun 7 '07 #13

P: n/a
Gianni Mariani <gi*******@mariani.wswrote in
news:46***********************@per-qv1-newsreader-01.iinet.net.au:
Ian Collins wrote:
>Gianni Mariani wrote:
>>Ian Collins wrote:
....
malloc(0)
Specified as far as you will either get a pointer to a block of >0
bytes or NULL, just like any other size.
That would be a problem then.

Why? What ever you get from malloc, you can pass to free.

Different behaviour on different systems. If I write code that
assumes malloc(0) returns unique values and it returns 0 on some, it
will break.

I'm not sure if that's the only one but it is a source of
inconsistency between platforms.
You need to check for the 0 anyway as that represents a failure to allocate
the memory. However you do end up with the indeterminate behaviour of "did
the memory allocation of 0 succeed, and I can continue to some sort of loop
(which will execute 0 times) and then free the pointer, or did it fail and
we need to do some sort of memory exhaustion error handling?", since the
malloc(0) could appear to be either case.
Jun 7 '07 #14

P: n/a
Gianni Mariani wrote:
Ian Collins wrote:
Gianni Mariani wrote:
Ian Collins wrote:
....
malloc(0)
Specified as far as you will either get a pointer to a block of
>0 bytes or NULL, just like any other size.
That would be a problem then.
>
>
Why? What ever you get from malloc, you can pass to free.

Different behaviour on different systems. If I write code that
assumes malloc(0) returns unique values and it returns 0 on some, it
will break.

I'm not sure if that's the only one but it is a source of
inconsistency between platforms.
It's ALWAYS possible that malloc() could return a null pointer.


Brian
Jun 7 '07 #15

P: n/a
desktop wrote:
I have read in Bjarne Stroustrup that using malloc and free should be
avoided in C++ because they deal with uninitialized memory and one
should instead use new and delete.

But why is that a problem? I cannot see why using malloc instead of
new does not give the same result.

As the others have pointed out, new invokes the constructor for types
that have one. Reasons to always use new:

1. Somewhat friendlier syntax, as malloc() requires a cast unless the
results are assigned to a void*, and you usually do some arithmetic in
the size calculation. Examples:

int* arr = static_cast<int*>(malloc(5 * sizeof *arr));

int* arr = new int[5];

2. It gives a more consistent allocating scheme, so that you don't have
a mix of new and malloc(). Of course, one of the pitfalls of C++ is the
difference between new and new[], requiring delete or delete[]. There
is only one deallocation for malloc().

3. If you change your mind on a previously POD-type struct, you won't
have to find and change the malloc() calls.


Brian
Jun 7 '07 #16

P: n/a
On Thu, 07 Jun 2007 21:12:33 +1200, Ian Collins wrote:
Torsten Mueller wrote:
>desktop <ff*@sss.comschrieb:
>>I have read in Bjarne Stroustrup that using malloc and free should
be avoided in C++ because they deal with uninitialized memory and
one should instead use new and delete.

But why is that a problem? I cannot see why using malloc instead of
new does not give the same result.

But there's another major reason for using new and delete: they are
much more portable while malloc/calloc/alloca/realloc/... are not. You
will normally never get a problem using new and delete, also on
different plattforms with different processors, because they
encapsulate all calls to the native malloc functions safely. These
operators belong to the language itself, not to the runtime library.
So you will normally not find includes of different headers and calls
to different allocation functions (both handled by conditional
compilation) and complicated casts for heap objects in strict C++
programs.
I don't follow that paragraph, what isn't portable about the malloc
family of standard library functions?
Time for me to open mouth...Insert foot...Yep, it fits...

But, if my assumption is correct, that new and delete can be
reimplemented (I think I read that somewhere), then yes, malloc and free
would seem less portable in a class hierarchy since they only work on
heap memory. Suppose new and delete are reimplemented to do weird stuff
like using a non-standard memory pool. Granted, I've never had a reason to
do such an esoteric mess but what then?

Jun 7 '07 #17

P: n/a
no***@all.com wrote:
On Thu, 07 Jun 2007 21:12:33 +1200, Ian Collins wrote:
>Torsten Mueller wrote:
>>desktop <ff*@sss.comschrieb:

I have read in Bjarne Stroustrup that using malloc and free should
be avoided in C++ because they deal with uninitialized memory and
one should instead use new and delete.

But why is that a problem? I cannot see why using malloc instead of
new does not give the same result.
But there's another major reason for using new and delete: they are
much more portable while malloc/calloc/alloca/realloc/... are not. You
will normally never get a problem using new and delete, also on
different plattforms with different processors, because they
encapsulate all calls to the native malloc functions safely. These
operators belong to the language itself, not to the runtime library.
So you will normally not find includes of different headers and calls
to different allocation functions (both handled by conditional
compilation) and complicated casts for heap objects in strict C++
programs.
I don't follow that paragraph, what isn't portable about the malloc
family of standard library functions?

Time for me to open mouth...Insert foot...Yep, it fits...

But, if my assumption is correct, that new and delete can be
reimplemented (I think I read that somewhere), then yes, malloc and free
would seem less portable in a class hierarchy since they only work on
heap memory. Suppose new and delete are reimplemented to do weird stuff
like using a non-standard memory pool. Granted, I've never had a reason to
do such an esoteric mess but what then?
Then the application that uses this non-standard memory pool isn't portable.

--
Ian Collins.
Jun 7 '07 #18

P: n/a
Default User wrote:
Gianni Mariani wrote:
....
>Different behaviour on different systems. If I write code that
assumes malloc(0) returns unique values and it returns 0 on some, it
will break.
....
>
It's ALWAYS possible that malloc() could return a null pointer.
Yes. The inference being my code will now magically work ?

How does this not break code that assumes a non-failure case returns
non-null ?
Jun 7 '07 #19

P: n/a
Gianni Mariani wrote:
Default User wrote:
Gianni Mariani wrote:
...
Different behaviour on different systems. If I write code that
assumes malloc(0) returns unique values and it returns 0 on some,
it will break.
>

...

It's ALWAYS possible that malloc() could return a null pointer.

Yes. The inference being my code will now magically work ?

How does this not break code that assumes a non-failure case returns
non-null ?
I don't understand the question. What results would you expect from
malloc(0)? Why would the implementation-defined nature make a
difference? Even when malloc(0) "succeeds", that is returns a non-null
pointer, you can't access the allocated memory. All you can do is
compare the pointer for equality or pass it to free().


Brian
Jun 7 '07 #20

P: n/a
On Jun 7, 2:14 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
Default User wrote:
Gianni Mariani wrote:
...
Different behaviour on different systems. If I write code that
assumes malloc(0) returns unique values and it returns 0 on some, it
will break.

...
It's ALWAYS possible that malloc() could return a null pointer.

Yes. The inference being my code will now magically work ?

How does this not break code that assumes a non-failure case returns
non-null ?
If that code is correctly written then it will simply see malloc as
consistently failing iff it returns NULL on malloc(0). Returning NULL
from malloc(0) is not magically a success case for that one input
value and a failure case for every other value.

Any code that assumes malloc won't return NULL and isn't prepared to
handle it is already broken, regardless of the parameter to malloc.

Jun 7 '07 #21

P: n/a
Default User wrote:
Gianni Mariani wrote:
....
>
I don't understand the question. What results would you expect from
malloc(0)?
I think that was already covered.
... Why would the implementation-defined nature make a
difference?
You can't figure that out ?
... Even when malloc(0) "succeeds", that is returns a non-null
pointer, you can't access the allocated memory.
Why do you need to access the memory - you have a pointer.
... All you can do is
compare the pointer for equality or pass it to free().
Exactly.

So what don't you get ?
Jun 7 '07 #22

P: n/a
Owen Jacobson wrote:
....
Any code that assumes malloc won't return NULL and isn't prepared to
handle it is already broken, regardless of the parameter to malloc.
Why is it broken ? It might be perfectly valid. I can think of at
least 2 examples of valid code that will work for one implementation of
malloc and not the other.
Jun 7 '07 #23

P: n/a
Gianni Mariani wrote:
Owen Jacobson wrote:
....
>Any code that assumes malloc won't return NULL and isn't prepared to
handle it is already broken, regardless of the parameter to malloc.

Why is it broken ? It might be perfectly valid. I can think of at
least 2 examples of valid code that will work for one implementation of
malloc and not the other.
Care to enlighten us?

--
Ian Collins.
Jun 7 '07 #24

P: n/a
Gianni Mariani wrote:
Ian Collins wrote:
>Gianni Mariani wrote:
>>Ian Collins wrote:
....
malloc(0)
Specified as far as you will either get a pointer to a block of >0
bytes
or NULL, just like any other size.
That would be a problem then.

Why? What ever you get from malloc, you can pass to free.

Different behaviour on different systems. If I write code that assumes
malloc(0) returns unique values and it returns 0 on some, it will break.
Why would you want to do that?

--
Ian Collins.
Jun 7 '07 #25

P: n/a
Ian Collins wrote:
Gianni Mariani wrote:
>Owen Jacobson wrote:
....
>>Any code that assumes malloc won't return NULL and isn't prepared to
handle it is already broken, regardless of the parameter to malloc.
Why is it broken ? It might be perfectly valid. I can think of at
least 2 examples of valid code that will work for one implementation of
malloc and not the other.

Care to enlighten us?
struct mystring
{

mystring( int len )
: len( len ),
ptr( malloc( len )
{
if ( ! ptr )
{
throw bad_alloc;
}
}
......

};
Jun 7 '07 #26

P: n/a
Ian Collins wrote:
....
Why would you want to do that?
I would not.

Have you forgotten the topic of this thread ? Why are you asking that
question ?
Jun 7 '07 #27

P: n/a
On Jun 7, 3:41 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
Ian Collins wrote:
Gianni Mariani wrote:
Owen Jacobson wrote:
....
Any code that assumes malloc won't return NULL and isn't prepared to
handle it is already broken, regardless of the parameter to malloc.
Why is it broken ? It might be perfectly valid. I can think of at
least 2 examples of valid code that will work for one implementation of
malloc and not the other.
Care to enlighten us?

struct mystring
{

mystring( int len )
: len( len ),
ptr( malloc( len )
{
if ( ! ptr )
{
throw bad_alloc;
}
}
......

};
Allowing for typos (you're missing the closing ) on the initialisation
of ptr), I don't see anything about that code that's broken by
malloc(0) returning NULL. The constructor as written validates the
assumption that a block of memory representing the string is available
and fails construction if not. That's a perfectly reasonable
assumption for the ensuing, elided code to make.

Keep in mind that, as written, malloc(23) is allowed to always return
NULL too -- it's a quality of implementation issue that it doesn't,
not a conformance issue. On such a system, mystring(23) would always
fail because the assumption it validates is not satisfied by that
system.

Jun 7 '07 #28

P: n/a
Gianni Mariani wrote:
Ian Collins wrote:
....
>Why would you want to do that?

I would not.

Have you forgotten the topic of this thread ? Why are you asking that
question ?
This branch has drifted away form the original question and descended
into a pointless argument about the portability of malloc(0), which you
have just conceded you wouldn't do.

--
Ian Collins.
Jun 7 '07 #29

P: n/a
Gianni Mariani wrote:
Default User wrote:
Gianni Mariani wrote:
...

I don't understand the question. What results would you expect from
malloc(0)?

I think that was already covered.
... Why would the implementation-defined nature make a
difference?

You can't figure that out ?
No, I can't.
... Even when malloc(0) "succeeds", that is returns a non-null
pointer, you can't access the allocated memory.

Why do you need to access the memory - you have a pointer.
For what purpose?
... All you can do is
compare the pointer for equality or pass it to free().

Exactly.
Exactly what?
So what don't you get ?
What you would expect the code do? What differential behavior would be
important to program flow?


Brian

Jun 7 '07 #30

P: n/a
On Jun 7, 11:37 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
Different behaviour on different systems. If I write code that
assumes malloc(0) returns unique values and it returns 0 on some,
it will break.
It's your error for making assumptions not guaranteed
by the standard. If I write code that assumes 'new'
never throws, should I blame the language when it
does throw?
I'm not sure if that's the only one but it is a source of
inconsistency between platforms.
If you want a language without implementation-defined
behaviour, then C++ is not for you.

Jun 7 '07 #31

P: n/a
Default User wrote:
....
>
What you would expect the code do? What differential behavior would be
important to program flow?
Because of different behaviour on different platforms, code may work on
one platform and not another. In the context of the OP, this suggests
to use new over malloc since the standard behaviour for new is
consistent across all platforms (modulo bugs).
Jun 8 '07 #32

P: n/a
Owen Jacobson wrote:
On Jun 7, 3:41 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
....
>struct mystring
{

mystring( int len )
: len( len ),
ptr( malloc( len )
{
if ( ! ptr )
{
throw bad_alloc;
}
}
......

};

Allowing for typos (you're missing the closing ) on the initialisation
of ptr), I don't see anything about that code that's broken by
malloc(0) returning NULL.

What about that exception on one platform and not another for mystring(0) ?

It's a really simple concept here, why don't you get it ? Different
"standard" behaviour on different platforms leads to less portable code
which is the statement Torsten made which is now obvious.

Sure *I* can write code that works correctly on all platforms, so what ?
The read question is, can there exist conforming code that works on
one platform and not another. That is obviously true (by existence).
... The constructor as written validates the
assumption that a block of memory representing the string is available
and fails construction if not. That's a perfectly reasonable
assumption for the ensuing, elided code to make.

Keep in mind that, as written, malloc(23) is allowed to always return
NULL too -- it's a quality of implementation issue that it doesn't,
not a conformance issue. On such a system, mystring(23) would always
fail because the assumption it validates is not satisfied by that
system.
What ? malloc(23) should only return null in the case of a bug (non
conformance) or inability to allocate memory (bad_alloc). Are you
advocating otherwise ?
Jun 8 '07 #33

P: n/a
Old Wolf wrote:
On Jun 7, 11:37 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
>Different behaviour on different systems. If I write code that
assumes malloc(0) returns unique values and it returns 0 on some,
it will break.

It's your error for making assumptions not guaranteed
by the standard. If I write code that assumes 'new'
never throws, should I blame the language when it
does throw?
Dear Old. It's not the point. The point is portability.

Jun 8 '07 #34

P: n/a
Ian Collins wrote:
Gianni Mariani wrote:
>Ian Collins wrote:
....
>>Why would you want to do that?
I would not.

Have you forgotten the topic of this thread ? Why are you asking that
question ?

This branch has drifted away form the original question and descended
into a pointless argument about the portability of malloc(0), which you
have just conceded you wouldn't do.
I never said I would do. I've seen code that does.

You may have thought that the thread topic drifted, I didn't which may
seem to explain why it went this way.
Jun 8 '07 #35

P: n/a
On Jun 7, 5:23 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
Owen Jacobson wrote:
On Jun 7, 3:41 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
...
struct mystring
{
mystring( int len )
: len( len ),
ptr( malloc( len )
{
if ( ! ptr )
{
throw bad_alloc;
}
}
......
};
Allowing for typos (you're missing the closing ) on the initialisation
of ptr), I don't see anything about that code that's broken by
malloc(0) returning NULL.

What about that exception on one platform and not another for mystring(0) ?
Or, for that matter, the exception that that code throws sometimes but
not other times on a single platform, within the same execution? Or
that that code always throws on a given platform, when run under high
load, but never throws on the same platform under low load? Or any of
a number of other circumstances?
Keep in mind that, as written, malloc(23) is allowed to always return
NULL too -- it's a quality of implementation issue that it doesn't,
not a conformance issue. On such a system, mystring(23) would always
fail because the assumption it validates is not satisfied by that
system.

What ? malloc(23) should only return null in the case of a bug (non
conformance) or inability to allocate memory (bad_alloc). Are you
advocating otherwise ?
The C standard, from whence malloc comes, is extremely conservative
when it comes to defining what standard library functions that have
side effects are required to do. The verbiage in C99 is as follows:

If the space cannot be allocated, a null pointer is
returned.

It does not say "If the space is unavailable", or "If memory is full",
or anything else, merely "if the space cannot be allocated." As I
said: it's a quality of implementation issue; a sufficiently poor
implementation may never be able to allocate exactly 23 bytes and
unwilling to allocate more than requested. Such an implementation
would be conformant, even though it would likely have no users.

The standard does continue on to describe what appears to be a special
case for malloc(0):

If the size of the space requested is zero, the behavior is
implementation-
defined: either a null pointer is returned, or the behavior is as if
the size
were some nonzero value, except that the returned pointer shall not
be used
to access an object.

However, on closer analysis both of these cases can be derived from
the general behaviour of malloc described elsewhere: 1. that
arithmetic on the returned pointer be limited to the half-open
interval [x, x+size), which is an empty interval when size is 0, and
2. that malloc may return NULL. Therefore this is not a special case,
and implementations that return NULL on malloc(0) even when memory is
available are merely poor implementations.

Isn't it time to get these implementations fixed, Gianni?

Jun 8 '07 #36

P: n/a
Oh, dammit. I haven't been quite precise enough.

On Jun 7, 6:44 pm, Owen Jacobson <angrybald...@gmail.comwrote:
1. that arithmetic on the returned pointer be limited to the half-open
interval [x, x+size), which is an empty interval when size is 0
1. That only pointers that fall in that half-open interval may be
*dereferenced* -- valid pointer values are actually those in the
closed interval [x, x+size], which has exactly one element (x) for
size = 0.

Jun 8 '07 #37

P: n/a
On Jun 7, 1:12 pm, desktop <f...@sss.comwrote:
I have read in Bjarne Stroustrup that using malloc and free should be
avoided in C++ because they deal with uninitialized memory and one
should instead use new and delete.

But why is that a problem? I cannot see why using malloc instead of new
does not give the same result.
Please refer below, I had modified recently -
http://wiki.answers.com/Q/What_is_th...er_than_syntax

BR
Mukesh

Jun 8 '07 #38

P: n/a
On Fri, 08 Jun 2007 08:41:43 +1000, Gianni Mariani
<gi*******@mariani.wswrote in comp.lang.c++:
Ian Collins wrote:
Gianni Mariani wrote:
Owen Jacobson wrote:
....
Any code that assumes malloc won't return NULL and isn't prepared to
handle it is already broken, regardless of the parameter to malloc.
Why is it broken ? It might be perfectly valid. I can think of at
least 2 examples of valid code that will work for one implementation of
malloc and not the other.
Care to enlighten us?

struct mystring
{

mystring( int len )
: len( len ),
ptr( malloc( len )
{
if ( ! ptr )
Replace the line above with:

if (len && !ptr)
{
throw bad_alloc;
}
}
......

};
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Jun 8 '07 #39

P: n/a
Owen Jacobson wrote:
>... Or any of
a number of other circumstances?
Chinese fish prices not withstanding ?

I don't see the relevance of this to this thread. We're talking about
portability issues of malloc over new. Someone assered that malloc
behaves differently on different platforms. My recollection was that
free(0) and malloc(0) used to be poorly specified. Someone said that
malloc(0) has two standard behaviours and I said QED. How this relates
to code throwing exceptions is about as relevant as PRC fish prices.

....
>What ? malloc(23) should only return null in the case of a bug (non
conformance) or inability to allocate memory (bad_alloc). Are you
advocating otherwise ?

The C standard, from whence malloc comes, is extremely conservative
when it comes to defining what standard library functions that have
side effects are required to do. The verbiage in C99 is as follows:

If the space cannot be allocated, a null pointer is
returned.

It does not say "If the space is unavailable", or "If memory is full",
or anything else, merely "if the space cannot be allocated."
Reread what I wrote. If it's not nearly identical to what you assert
then I don't understand.
... As I
said: it's a quality of implementation issue; a sufficiently poor
implementation may never be able to allocate exactly 23 bytes and
unwilling to allocate more than requested.
Again this is relevant to this discussion how ? The "mystring" code I
hacked earlier is an example where on one platform malloc(0) returning
different values on different platforms causing vastly different things
to happen being a portability issue. That's all. Code like this
exists. The point is that new has a more strict definition and hence it
will result in better code portability. It seems damn obvious to me,
why cant you see it.
... Such an implementation
would be conformant, even though it would likely have no users.
Again, so what ? The point is that code (bad or otherwise) exists such
that it works on one platform and not another because of THIS behaviour
of malloc which does not happen with new. That's all. If you think it
does not exist, see my code above. If you don't believe that anyone
would write code like that, get more experience.
>
The standard does continue on to describe what appears to be a special
case for malloc(0):

If the size of the space requested is zero, the behavior is
implementation-
defined: either a null pointer is returned, or the behavior is as if
the size
were some nonzero value, except that the returned pointer shall not
be used
to access an object.
Very nice. Rather a stupid thing to put in the standard IMHO.
>
However, on closer analysis both of these cases can be derived from
the general behaviour of malloc described elsewhere: 1. that
arithmetic on the returned pointer be limited to the half-open
interval [x, x+size), which is an empty interval when size is 0, and
2. that malloc may return NULL. Therefore this is not a special case,
and implementations that return NULL on malloc(0) even when memory is
available are merely poor implementations.
Poor but compliant making the fault that of the standard.
>
Isn't it time to get these implementations fixed, Gianni?
Sure. By that question do you imply you want me to do something about
it? You seem to have a grasp of the issue, you're just as qualified as
I am. Good luck with the C committee.

Jun 8 '07 #40

P: n/a
Jack Klein wrote:
....
>
Replace the line above with:

if (len && !ptr)
You're ability to resolve this instance of problem is uncontested.

I bet you can't fix this problem in my source files without getting
access to them or changing the behaviour of malloc on all systems !
Jun 8 '07 #41

P: n/a
On Jun 7, 8:09 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
Owen Jacobson wrote:
... Or any of
a number of other circumstances?

Chinese fish prices not withstanding ?
That's what "implementation defined" means, yes. The entire behaviour
of malloc is, somewhat obliquely, implementation-defined. The only
properties malloc must have in a conforming implementation is always
producing any of a fixed set of outputs for any given input, and that
subsequent operations on those values also have predictable results.
I don't see the relevance of this to this thread. We're talking about
portability issues of malloc over new. Someone assered that malloc
behaves differently on different platforms. My recollection was that
free(0) and malloc(0) used to be poorly specified. Someone said that
malloc(0) has two standard behaviours and I said QED. How this relates
to code throwing exceptions is about as relevant as PRC fish prices.
The assertion that malloc is somehow "less portable" than new is so
wrong-headed that I thought I'd have a shot at dismantling it. Plus,
I like replying to you.
What ? malloc(23) should only return null in the case of a bug (non
conformance) or inability to allocate memory (bad_alloc). Are you
advocating otherwise ?
The C standard, from whence malloc comes, is extremely conservative
when it comes to defining what standard library functions that have
side effects are required to do. The verbiage in C99 is as follows:
If the space cannot be allocated, a null pointer is
returned.
It does not say "If the space is unavailable", or "If memory is full",
or anything else, merely "if the space cannot be allocated."

Reread what I wrote. If it's not nearly identical to what you assert
then I don't understand.
Ah, but your point, as I read it, was that malloc's behaviour when
passed 0 as an argument was somehow less well-specified than its
behaviour in the face of other inputs. This is, as supported by
careful examination of the C standard, not true. Code which relies on
malloc returning a non-NULL pointer, and code which relies on new
returning a pointer rather than throwing an exception, *must* be
prepared for the alternative as it will eventually happen in all but
the most trivial examples. Period.
... As I
said: it's a quality of implementation issue; a sufficiently poor
implementation may never be able to allocate exactly 23 bytes and
unwilling to allocate more than requested.

Again this is relevant to this discussion how ? The "mystring" code I
hacked earlier is an example where on one platform malloc(0) returning
different values on different platforms causing vastly different things
to happen being a portability issue.
Neither the C nor the C++ standard guarantees that conforming code
will behave identically on all platforms. They guarantee that
conforming code will behave *predictably* on all conforming
platforms. This is true of all programming languages that have formal
definitions.
That's all. Code like this
exists. The point is that new has a more strict definition
Cite from the relevant standards? I don't see any evidence that
that's actually true.
and hence it will result in better code portability.
*If* 'new' has a more strict definition than malloc, then code that
utilises 'new' will have a more strictly-defined behaviour than code
that uses malloc, yes.
... Such an implementation
would be conformant, even though it would likely have no users.

Again, so what ? The point is that code (bad or otherwise) exists such
that it works on one platform and not another because of THIS behaviour
of malloc which does not happen with new. That's all. If you think it
does not exist, see my code above. If you don't believe that anyone
would write code like that, get more experience.
The same behaviour is permitted from new (and new[]). Nothing in the C
++ standard demands that a new-expression exhaust memory before
throwing std::bad_alloc -- in fact, the definition of new and new[] is
carefully written to allow malloc() as an allocator function[0].
Therefore, nothing prohibits a compliant C++ implementation from, by
default, throwing bad_alloc consistently on either of the two
following examples:

--example1.cpp--

class Empty {
};

int main () {
Empty *e = new Empty (); // Here

delete e;
}

--example2.cpp--

int main () {
int *i = new int[0]; // Here

delete i;
}

--end--

Once again, such an implementation would be conforming: the behaviour
of both programs is predictable. It would merely be extremely poor.
The standard does continue on to describe what appears to be a special
case for malloc(0):
....
However, on closer analysis both of these cases can be derived from
the general behaviour of malloc described elsewhere: 1. that
arithmetic on the returned pointer be limited to the half-open
interval [x, x+size), which is an empty interval when size is 0, and
2. that malloc may return NULL. Therefore this is not a special case,
and implementations that return NULL on malloc(0) even when memory is
available are merely poor implementations.

Poor but compliant making the fault that of the standard.
I find it hard to believe you expect the ISO standards committee to
control the behaviour of myriad implementation vendors, as that's what
enforcing any specific behaviour from a memory-allocation function
would require. It would also require absolute cooperation from OS
vendors and hardware manufacturers.
Isn't it time to get these implementations fixed, Gianni?

Sure. By that question do you imply you want me to do something about
it? You seem to have a grasp of the issue, you're just as qualified as
I am. Good luck with the C committee.
While I'm not psychic, I believe the C committee's goals to include
defining a language in which both extremely portable code and
extremely platform-dependant code may be written. Consequently, the
standard defines rules within which code is guaranteed to behave
predictably under any conforming implementation; it is up to
programmers to be familiar with these rules if they wish to write code
that's as portable as C allows. The language does not demand that all
code remain within these rules.

Owen

[0] The clause that demands that allocation functions return non-NULL
pointers on an argument of 0 bytes means that malloc may only be used
as a nothrow allocation function, which are allowed to return NULL to
indicate failure to allocate. Malloc may not be used as-is by an
implementation's default allocation function; however, this trivial
wrapper, as far as I can tell, may:

--trivial-malloc-wrapper.cpp--

#include <cctype>
#include <cstdlib>
#include <exception>

void *mallocator (std::size_t size) {
void *allocated = std::malloc (size);
if (!allocated) throw std::bad_alloc ();
return allocated;
}

--end--

Jun 8 '07 #42

P: n/a
On Jun 8, 12:26 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
Old Wolf wrote:
Gianni Mariani <gi3nos...@mariani.wswrote:
Different behaviour on different systems. If I write code that
assumes malloc(0) returns unique values and it returns 0 on
some, it will break.
It's your error for making assumptions not guaranteed
by the standard. If I write code that assumes 'new'
never throws, should I blame the language when it
does throw?

Dear Old. It's not the point. The point is portability.
Huh? Portable code is code that complies with
the standards. You can write portable code with
malloc, as evinced by the thousands of portable C
applications out there.

It seems you are criticizing malloc based on
a buggy code-snippet you wrote. I am saying
that it is not malloc being non-portable, it
is that your code has a bug.
Jun 8 '07 #43

P: n/a
On Jun 8, 3:09 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
The point is that new has a more strict definition and hence it
will result in better code portability. It seems damn obvious to me,
why cant you see it.
Nobody else can see it either .. perhaps it's you that's wrong?

Firstly, new does not have a more strict definition.
malloc(0) has two options:
- return NULL
- return valid pointer

new T[0] has three options:
- throw exception
- return valid pointer
- return NULL, if T has a custom allocator (see 5.3.4/13)

So it seems to me that 'new' is LESS strictly specified than malloc.

Secondly, strict definition doesn't mean more portable.
In fact, C and C++ specifications were deliberately
made as non-strict as possible, to _improve_ portability.

It's no coincidence that C is available on almost every
single platform that has anything other than assembly.

Jun 8 '07 #44

P: n/a
Owen Jacobson wrote:
On Jun 7, 8:09 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
>Owen Jacobson wrote:
>>... Or any of
a number of other circumstances?
Chinese fish prices not withstanding ?

That's what "implementation defined" means, yes. The entire behaviour
of malloc is, somewhat obliquely, implementation-defined. The only
properties malloc must have in a conforming implementation is always
producing any of a fixed set of outputs for any given input, and that
subsequent operations on those values also have predictable results.
This describes malloc and numerous other interfaces. Again, so ? Here
is some more info http://www.fa.gov.tw/eng/news/news.php.
>
>I don't see the relevance of this to this thread. We're talking about
portability issues of malloc over new. Someone assered that malloc
behaves differently on different platforms. My recollection was that
free(0) and malloc(0) used to be poorly specified. Someone said that
malloc(0) has two standard behaviours and I said QED. How this relates
to code throwing exceptions is about as relevant as PRC fish prices.

The assertion that malloc is somehow "less portable" than new is so
wrong-headed that I thought I'd have a shot at dismantling it. Plus,
I like replying to you.
In the context of the OP - what do you use - malloc or new ? Your less
likely to get into trouble using new if you don't know about malloc(0)
having two conforming behaviours. IIRC, the reason why I ended up
knowing about issues with free(0) and malloc(0) was when my own malloc
library did different things than the standard library and code started
to break everywhere. It became clear to me that wether I liked it or
not, malloc(0) should likely return non-null otherwise lots of code
broke. It was used in some cases as a process specific unique number
generator. In some cases strings of 0 length were allocated and
comparison of string pointer was an identifying mark of being the same
string. My initial work around for the "malloc bug" was to change the
length to 1 if it came in as zero but later I fixed the code so the
allocated block was actually 0 bytes long.

You may argue all you like about how portable malloc is but in reality I
have had alot of experience that tells me differently.
>
>>>What ? malloc(23) should only return null in the case of a bug (non
conformance) or inability to allocate memory (bad_alloc). Are you
advocating otherwise ?
The C standard, from whence malloc comes, is extremely conservative
when it comes to defining what standard library functions that have
side effects are required to do. The verbiage in C99 is as follows:
If the space cannot be allocated, a null pointer is
returned.
It does not say "If the space is unavailable", or "If memory is full",
or anything else, merely "if the space cannot be allocated."
Reread what I wrote. If it's not nearly identical to what you assert
then I don't understand.

Ah, but your point, as I read it, was that malloc's behaviour when
passed 0 as an argument was somehow less well-specified than its
behaviour in the face of other inputs.
malloc(0) just leads to novices creating code that may or may not be
portable. That's the only thing I was alluding to.
... This is, as supported by
careful examination of the C standard, not true.
By experience it is true. The C standard can say all it likes but
broken code exists and new broken code will continue to be written.
... Code which relies on
malloc returning a non-NULL pointer, and code which relies on new
returning a pointer rather than throwing an exception, *must* be
prepared for the alternative as it will eventually happen in all but
the most trivial examples. Period.
Never argued any different. However demanding it and getting it are two
very different things.
>
>>... As I
said: it's a quality of implementation issue; a sufficiently poor
implementation may never be able to allocate exactly 23 bytes and
unwilling to allocate more than requested.
Again this is relevant to this discussion how ? The "mystring" code I
hacked earlier is an example where on one platform malloc(0) returning
different values on different platforms causing vastly different things
to happen being a portability issue.

Neither the C nor the C++ standard guarantees that conforming code
will behave identically on all platforms. They guarantee that
conforming code will behave *predictably* on all conforming
platforms. This is true of all programming languages that have formal
definitions.
There is a certain level of expectation that calling "malloc(1)" at the
beinnging of main will return non zero. I have found numerous
applications that segv when it does not (when I was doing my malloc
testing). Even libc on many platforms died even before main() was
called when I did my tests 15 or so years ago. I suspect things are a
little better now.
>
> That's all. Code like this
exists. The point is that new has a more strict definition

Cite from the relevant standards? I don't see any evidence that
that's actually true.
What standard ? I wrote code in this thread earlier that works on one
platform and not on another - wether it's conforming or not is
irrelevant, the fact is that I know it exists because I ran into 10s of
applications that expected certain behaviour from malloc(0). It's proof
by existence.
>
>and hence it will result in better code portability.

*If* 'new' has a more strict definition than malloc, then code that
utilises 'new' will have a more strictly-defined behaviour than code
that uses malloc, yes.
Yes.
>
>>... Such an implementation
would be conformant, even though it would likely have no users.
Again, so what ? The point is that code (bad or otherwise) exists such
that it works on one platform and not another because of THIS behaviour
of malloc which does not happen with new. That's all. If you think it
does not exist, see my code above. If you don't believe that anyone
would write code like that, get more experience.

The same behaviour is permitted from new (and new[]). Nothing in the C
++ standard demands that a new-expression exhaust memory before
throwing std::bad_alloc -- in fact, the definition of new and new[] is
carefully written to allow malloc() as an allocator function[0].
Therefore, nothing prohibits a compliant C++ implementation from, by
default, throwing bad_alloc consistently on either of the two
following examples:

--example1.cpp--

class Empty {
};

int main () {
Empty *e = new Empty (); // Here

delete e;
}
Conforming or not, it would be a terribly useless compiler if it did
throw bad_alloc here. Hence I think none do unless memory really can't
be allocated as in it is exhasted by some implementation defined meaning
of exhausted.

Besides sizeof Empty is probably 1 on most implementations so it's not
relevant to this discussion when comparing it to malloc(0). The
standard requires that each object have a unique address. There is a
trivial base class optimization that does essentially make Empty zero
sized when derived from but compilers are free to simply sizeof Empty 1.
>
--example2.cpp--

int main () {
int *i = new int[0]; // Here

delete i;
}
I don't think any C++ compiler will throw here either (I have yet to see
one) unless memory is exhausted (by some implementation defined meaning
of ehausted).
>
--end--

Once again, such an implementation would be conforming: the behaviour
of both programs is predictable. It would merely be extremely poor.
.... and pointless.

Do you know of the existance of a platform that will consistantly throw
bad_alloc for "int *i = new int[0];" ?

....
>
I find it hard to believe you expect the ISO standards committee to
control the behaviour of myriad implementation vendors, as that's what
enforcing any specific behaviour from a memory-allocation function
would require.
What are standards for again ?
... It would also require absolute cooperation from OS
vendors and hardware manufacturers.
That's one of the side effects of standards.
>
>>Isn't it time to get these implementations fixed, Gianni?
Sure. By that question do you imply you want me to do something about
it? You seem to have a grasp of the issue, you're just as qualified as
I am. Good luck with the C committee.

While I'm not psychic, I believe the C committee's goals to include
defining a language in which both extremely portable code and
extremely platform-dependant code may be written.
What the committee wants to do is highly dependent of the committee
members. However, given that one of the most critical features of a
computer language like C and C++ is to have a certain degree of code
portability, I would expect that this one would be high on it's priority
list.
... Consequently, the
standard defines rules within which code is guaranteed to behave
predictably under any conforming implementation; it is up to
programmers to be familiar with these rules if they wish to write code
that's as portable as C allows.
Sigh. True. I have met too many programmers to know reality is
unfortunately different. The best thing is for the standards committee
to provide well defined behaviour where there is no compelling
implementation dependent reason to do otherwise. i.e. malloc(0) being
defined to behave like malloc(1) would have been a fine requirement in
the standard.
... The language does not demand that all
code remain within these rules.
What do you think we're discussing ?
Jun 8 '07 #45

P: n/a
Old Wolf wrote:
....
>
It seems you are criticizing malloc based on
a buggy code-snippet you wrote. I am saying
that it is not malloc being non-portable, it
is that your code has a bug.
my code ?

You really don't see the point ?
Jun 8 '07 #46

P: n/a
Gianni Mariani wrote:
Old Wolf wrote:
....
>>
It seems you are criticizing malloc based on
a buggy code-snippet you wrote. I am saying
that it is not malloc being non-portable, it
is that your code has a bug.

my code ?

You really don't see the point ?
The point is that no one appears to see your points. Maybe that should
tell you something.

--
Ian Collins.
Jun 8 '07 #47

P: n/a
On Jun 7, 11:25 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
Owen Jacobson wrote:
On Jun 7, 8:09 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
I don't see the relevance of this to this thread. We're talking about
portability issues of malloc over new. Someone assered that malloc
behaves differently on different platforms. My recollection was that
free(0) and malloc(0) used to be poorly specified. Someone said that
malloc(0) has two standard behaviours and I said QED. How this relates
to code throwing exceptions is about as relevant as PRC fish prices.
The assertion that malloc is somehow "less portable" than new is so
wrong-headed that I thought I'd have a shot at dismantling it. Plus,
I like replying to you.

In the context of the OP - what do you use - malloc or new ?
It depends entirely on what I (the OP, if I were) need it *for*,
actually. If all I need is a block of memory that's guaranteed to be
aligned and at least N chars large, malloc fits the bill perfectly.
If I need to create N objects, malloc obviously won't do and I need to
use new. If I need the returned memory to be of a specific type, I'm
very likely better off using new, though using malloc and casting the
return is acceptable for POD types. There are plenty of reasons to
use new in preference to malloc. The portability of malloc isn't one
of them.

Since the OP did not supply any context for his question on why
someone might prefer one over the other, the most appropriate answer
from this group is probably "it depends," though the other answers
given were mostly excellent. The various differences that are topical
here have been well covered.
IIRC, the reason why I ended up knowing about issues with free(0) and
malloc(0) was when my own malloc library did different things than the
standard library
....for your compiler and platform...
and code started to break everywhere. It became clear to me that wether
I liked it or not, malloc(0) should likely return non-null otherwise
lots of code broke. It was used in some cases as a process specific
unique number generator.
This is a usage not well-supported by malloc; while you can use it
that way, the standard only guarantees that IF malloc(n) returns a non-
NULL pointer at all, THEN that pointer will not be returned by malloc
again until passed to free. It does not guarantee that it will return
a non-NULL pointer at all, either for n = 0 or any other value of n.
In some cases strings of 0 length were allocated and
comparison of string pointer was an identifying mark of being the same
string. My initial work around for the "malloc bug" was to change the
length to 1 if it came in as zero but later I fixed the code so the
allocated block was actually 0 bytes long.

You may argue all you like about how portable malloc is but in reality I
have had alot of experience that tells me differently.
Take a moment to consider the Newsgroups: header on this post, and the
topic area of the newsgroups listed there. The original question, and
all subsequent discussion, is mostly being taken in the context of the
standard C++ programming language, not any specific implementation.
Had I been reading, say, comp.os.linux.development, I would've
immediately turned to the man page on malloc and the g++ standard
library documentation to consider quirks of the usual C and C++
libraries available under Linux before getting involved.
Ah, but your point, as I read it, was that malloc's behaviour when
passed 0 as an argument was somehow less well-specified than its
behaviour in the face of other inputs.

malloc(0) just leads to novices creating code that may or may not be
portable. That's the only thing I was alluding to.
The behaviour of incorrect code, no matter who wrote it, is outside
the scope of the C++ language, and the C language.
... This is, as supported by
careful examination of the C standard, not true.

By experience it is true. The C standard can say all it likes but
broken code exists and new broken code will continue to be written.
If you wish to discuss implementation-specific behaviour, there are
places for exactly that. comp.lang.c++ is rarely one of them.
Because compilers are deterministic, you can very likely derive the
exact expected behaviour for any given bit of "invalid" code under a
specific compiler by reading that compiler's documentation or
experimenting with that compiler's output.
That's all. Code like this
exists. The point is that new has a more strict definition
Cite from the relevant standards? I don't see any evidence that
that's actually true.

What standard ? I wrote code in this thread earlier that works on one
platform and not on another - wether it's conforming or not is
irrelevant, the fact is that I know it exists because I ran into 10s of
applications that expected certain behaviour from malloc(0). It's proof
by existence.
Actually, from the point of view of the C++ programming language, the
code you wrote works perfectly under both outcomes. It just doesn't
do what you want it to under one of them. I realize that sounds like
semantic niggling, but "works" is a very vague term, whereas "has well-
defined results" isn't.

I'm aware that you're using a definition of "works" that means "the
constructor completes without an exception." However, the code you've
written does not necessarily do that. If you want that behaviour, you
have to program for it yourself. This is not because of a flaw in
malloc; it is because of a difference between the code you wrote and
the code you intended to write. A bug, in other words, for which
you've already been offered a solution. Similar instances of bad
assumptions in code outside your control should be taken up with that
code's author.
The same behaviour is permitted from new (and new[]). Nothing in the C
++ standard demands that a new-expression exhaust memory before
throwing std::bad_alloc -- in fact, the definition of new and new[] is
carefully written to allow malloc() as an allocator function[0].
Therefore, nothing prohibits a compliant C++ implementation from, by
default, throwing bad_alloc consistently on either of the two
following examples:
....
--example2.cpp--
int main () {
int *i = new int[0]; // Here
delete i;
}

I don't think any C++ compiler will throw here either (I have yet to see
one) unless memory is exhausted (by some implementation defined meaning
of ehausted).
A lack of proof that this can happen is not a proof that this can't
happen.
Once again, such an implementation would be conforming: the behaviour
of both programs is predictable. It would merely be extremely poor.

... and pointless.
Absolutely. I don't mean that any serious implementation would have
glaring flaws like that.
Do you know of the existance of a platform that will consistantly throw
bad_alloc for "int *i = new int[0];" ?
No. Nor do I assume it will never happen, except by accident.
I find it hard to believe you expect the ISO standards committee to
control the behaviour of myriad implementation vendors, as that's what
enforcing any specific behaviour from a memory-allocation function
would require.

What are standards for again ?
In this case, to define what behaviour is mandatory and what is up to
each implementation. You're asserting that, because some
implementations make use of the leeway the standard gives them, even
though that leeway is well-signposted for the language's users and has
very clear boundaries, it somehow weakens the portability of code that
takes those implementation-defined areas under consideration.
... It would also require absolute cooperation from OS
vendors and hardware manufacturers.

That's one of the side effects of standards.
No OS I know of acts as though bound by a mere language specification,
nor do hardware vendors design their chips and boards first with C
programmers in mind and second with the real task. It's up to the
language implementors for each platform to make their implementation
conform to the standard (which on the whole they do), not up to the
language standard to force each platform to conform it.
While I'm not psychic, I believe the C committee's goals to include
defining a language in which both extremely portable code and
extremely platform-dependant code may be written.

What the committee wants to do is highly dependent of the committee
members. However, given that one of the most critical features of a
computer language like C and C++ is to have a certain degree of code
portability, I would expect that this one would be high on it's priority
list.
In my experience it is a high priority. In my experience code that
remains within the bounds of the C++ specification and which makes no
unwarranted assumptions *is* highly portable. Code that makes invalid
assumptions is, to varying degrees, less portable; it's a necessary
price to pay for allowing implementations to support things outside
the C++ standard.

Frankly, once you're into dynamic memory management, you're well into
portability Bat Country no matter how tidy the language is. Here's a
poser for you: write a clear, unambiguous specification for a function
much like malloc which takes a size and returns a pointer to a memory
block at least that large that is not circular in any way and does not
contain an out like C's "implementation-defined behaviour." I tried;
every attempt eventually became circular or involved dragging in
specific environmental features like memory managers.

Even Java doesn't guarantee that "new byte[0];" at the beginning of
execution will succeed, only that if it does succeed it will return a
reference to a 0-element byte array -- exactly the same guarantee made
by C++, and exactly the same guarantee made by C for malloc (0).
... Consequently, the
standard defines rules within which code is guaranteed to behave
predictably under any conforming implementation; it is up to
programmers to be familiar with these rules if they wish to write code
that's as portable as C allows.

Sigh. True. I have met too many programmers to know reality is
unfortunately different. The best thing is for the standards committee
to provide well defined behaviour where there is no compelling
implementation dependent reason to do otherwise. i.e. malloc(0) being
defined to behave like malloc(1) would have been a fine requirement in
the standard.
It is defined like malloc(1). The clause about malloc(0) being
permitted to do either of two things applies equally well to malloc(n)
for all n in size_t. It is a warning that some implementations are
going to break a particularly common but bad assumption more often for
0 than for other values, and nothing more.
Again, so what ? The point is that code (bad or otherwise) exists such
that it works on one platform and not another because of THIS behaviour
of malloc which does not happen with new. That's all. If you think it
does not exist, see my code above. If you don't believe that anyone
would write code like that, get more experience.
As it happens, I've written code that makes all sorts of invalid
assumptions about standard library functions. When it eventually
crashed, I had to learn how and why my assumptions were wrong, which
meant reading both the specification and the documentation for the
implementation. Frequently, it also meant reading the implementation
itself.

Writing correct code that does what you mean it to do is *hard*. C++
does not go out of its way to make it easy, favouring powerful
features over "safe" ones; consequently, incorrect code tends to be
*very* incorrect.

Jun 8 '07 #48

P: n/a
Owen Jacobson wrote:
On Jun 7, 11:25 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
>Owen Jacobson wrote:
>>On Jun 7, 8:09 pm, Gianni Mariani <gi3nos...@mariani.wswrote:
I would never have imagined that malloc(0) could have generated so much
discussion. Let's get back to the OP question.

Do we agree this is an appropriate answer ?

I and at least one other is insane for perpetuating this dribble.

The OP wants to know if malloc is acceptable in C++ code - Yes it is.

Should one prefer new over malloc - answer - depends. new is
significantly better for most uses and *seems* to provide more
consistant behaviour than malloc(0) (edge case).

If "realloc()" behaviour is needed for very large blocks of memory, then
malloc() is the only standard choice that provides potentially
significant performance improvements.

As for the rest of your post. If you really really really care, I'll
respond but it's getting beyond silly.
Jun 8 '07 #49

P: n/a
Ian Collins wrote:
Gianni Mariani wrote:
>Old Wolf wrote:
....
>>It seems you are criticizing malloc based on
a buggy code-snippet you wrote. I am saying
that it is not malloc being non-portable, it
is that your code has a bug.
my code ?

You really don't see the point ?

The point is that no one appears to see your points. Maybe that should
tell you something.
The point is this: malloc(0) on some platforms always returns null while
on others it returns a 0 sized block of memory (essentially no different
than if you had called malloc(1)).

Hence someone who writes code like the example I posted, is potentially
going to run into trouble with platforms that return null on malloc(0)
and hence it's a portability issue.

If this is all fixed now and all modern versions of malloc behave in the
same way - then we're all good, however this was a problem 15 years ago.
Jun 8 '07 #50

71 Replies

This discussion thread is closed

Replies have been disabled for this discussion.