problem with memcpy and pointers/arrays confusion - again

  • Thread starter =?ISO-8859-1?Q?Martin_J=F8rgensen?=
  • Start date
R

Richard Heathfield

Martin Jørgensen said:
Michael said:
Martin said:
int *int_array = (int *) alloc_mem( N, sizeof(int_array[0]), __FILE__,
__LINE__, &total_mem);


Why are you casting? void* can be converted to int* implicitly.
Same argument as for malloc() itself.

Hmmm. I don't know. Hopefully it's because I got a compiler warning and
then wanted to get rid of it... Can't exactly remember if there was any
reason at all...

The correct way to get rid of the warning is to include a header that gives
the prototype of the alloc_mem function.
 
M

Martin Joergensen

"Richard Heathfield" <[email protected]> skrev i en
meddelelse
Martin Jørgensen said:
Michael said:
Martin Joergensen schrieb:

int *int_array = (int *) alloc_mem( N, sizeof(int_array[0]),
__FILE__,
__LINE__, &total_mem);


Why are you casting? void* can be converted to int*
implicitly.
Same argument as for malloc() itself.

Hmmm. I don't know. Hopefully it's because I got a compiler
warning and
then wanted to get rid of it... Can't exactly remember if
there was any
reason at all...

The correct way to get rid of the warning is to include a
header that gives
the prototype of the alloc_mem function.

I don't think that is possible, because I wanted the function to
be universally and should work both both int*, double* char* and
whatever?

void *alloc_mem (size_t num_elems, size_t elem_size,...);

I guess that sometimes I'll have to use:

int *int_array = (int *) alloc_mem( N, sizeof(int_array[0]),
__FILE__,

and other times:

double *double_array = (double *) alloc_mem( N,
sizeof(int_array[0]), __FILE__,

Wouldn't I??? I think actually that is why I made this cast....
If you have a better suggestion for this universal function, let
me hear. If I made int * in the prototype then the function
wouldn't work for double *, I guess...


Best regards / Med venlig hilsen
Martin Jørgensen
 
R

Richard Heathfield

Martin Joergensen said:
[...] I wanted the function to
be universally and should work both both int*, double* char* and
whatever?

void *alloc_mem (size_t num_elems, size_t elem_size,...);

That's fine - just stick that prototype in a header, and #include the header
in code that uses that prototype.
I guess that sometimes I'll have to use:

int *int_array = (int *) alloc_mem( N, sizeof(int_array[0]),
__FILE__,

and other times:

double *double_array = (double *) alloc_mem( N,
sizeof(int_array[0]), __FILE__,

Wouldn't I???

No. You do NOT need the cast. Just use void * for the return type.
I think actually that is why I made this cast....
If you have a better suggestion for this universal function, let
me hear. If I made int * in the prototype then the function
wouldn't work for double *, I guess...

That's why you use void *
 
M

Martin Joergensen

"Richard Heathfield" <[email protected]> skrev i en
meddelelse
Martin Joergensen said: -snip-
I guess that sometimes I'll have to use:

int *int_array = (int *) alloc_mem( N, sizeof(int_array[0]),
__FILE__,

and other times:

double *double_array = (double *) alloc_mem( N,
sizeof(int_array[0]), __FILE__,

Wouldn't I???

No. You do NOT need the cast. Just use void * for the return
type.

Oh, I see... Thanks...
That's why you use void *

Ok.... If I didn't get a warning, then it's strange I made that
cast... Thanks for commenting.... Hopefully I'll soon learn :)

Best regards / Med venlig hilsen
Martin Jørgensen
 
F

Flash Gordon

Martin said:
Ok.... If I didn't get a warning, then it's strange I made that cast...
Thanks for commenting.... Hopefully I'll soon learn :)

Rules of using casts:
1) If the compiler gives you a warning don't *ever* add a cast to fix it
2) Don't put in a cast unless you know it is required and know *why* it
is required. A compiler warning does not count, see 1 above.
3) If you appear to need a cast then work out what you are doing wrong,
because 9 times out of 10 you don't need to use a cast.
4) Only on those very rare occasions where you need a cast and you know
and understand why you need to cast do you cast.
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Flash said:
Martin Joergensen wrote: -snip-

Rules of using casts:
1) If the compiler gives you a warning don't *ever* add a cast to fix it

Hmm. That's the only way I can think of sometimes... I don't have any
examples now - I'll post one next time I don't know how to get rid of
the warning.
2) Don't put in a cast unless you know it is required and know *why* it
is required. A compiler warning does not count, see 1 above.
3) If you appear to need a cast then work out what you are doing wrong,
because 9 times out of 10 you don't need to use a cast.
4) Only on those very rare occasions where you need a cast and you know
and understand why you need to cast do you cast.

I think I know why I did that cast. From
http://en.wikipedia.org/wiki/Malloc :

int *ptr = (int *)malloc(sizeof(int) * 10);

But that cast is wrong, you say? Then somebody should update what's on
wikipedia...


Best regards / Med venlig hilsen
Martin Jørgensen
 
V

Vladimir S. Oka

Martin Jørgensen opined:
From
http://en.wikipedia.org/wiki/Malloc :

int *ptr = (int *)malloc(sizeof(int) * 10);

But that cast is wrong, you say? Then somebody should update
what's on wikipedia...

It is not wrong (illegal) per se.

There are actually two problems with the line above:

a) cast will mask non-inclusion of stdlib.h
(that's why you shouldn't cast)
b) it's more future-proof to write:

int *ptr = malloc(10 * sizeof *ptr);

as then you don't have to change it once the
type pointed to by `ptr` changes.

PS
It's also better to use a #define instead of 10.

--
BR, Vladimir

Kramer's Law:
You can never tell which way the train went by looking at the
track.
 
A

Al Balmer

I think I know why I did that cast. From
http://en.wikipedia.org/wiki/Malloc :

int *ptr = (int *)malloc(sizeof(int) * 10);

But that cast is wrong, you say? Then somebody should update what's on
wikipedia...

You can update it yourself. In fact, that's one of the main problems
with Wikipedia. I'm beginning to think that its dangers outweigh its
usefulness.

More and more people seem to be unquestioningly accepting Wikipedia as
authoritative.
 
K

Keith Thompson

Martin Jørgensen said:
I think I know why I did that cast. From
http://en.wikipedia.org/wiki/Malloc :

int *ptr = (int *)malloc(sizeof(int) * 10);

But that cast is wrong, you say? Then somebody should update what's on
wikipedia...

Looks like someone has:

#include <stdlib.h>

/* Allocate space for an array with 10 elements of type int */
/* C++ needs a cast, C strongly discourages it */
int *ptr = malloc(sizeof *ptr * 10);
if (!ptr)
exit(1); /* We could not allocate any memory, so exit */

/* allocation succeeded */

But someone should still change the exit(1) to exit(EXIT_FAILURE).
 
D

Dave Thompson

On 2006-03-13, Keith Thompson <[email protected]> wrote:

#if __STDC_VERSION__ == 199901l
#define prntZ "z"
#elif SIZE_MAX <= UINT_MAX && sizeof(size_t) <= sizeof(int)
#define prntZ ""
#elif SIZE_MAX == ULONG_MAX && sizeof(size_t) == sizeof(long)
#define prntZ "l"
#else
#error size_t too big
#endif
sizeof, and sizeof(typename), doesn't standardly work in preprocessor
directives, although there are rumors some compilers support it.

With that removed, it will work on any reasonable implementation,
although it is formally permitted (though massively stupid) for u-int
and u-long (or similar other pairs of types) to have the same range
but different representations (either the same size or different).
To be paranoid you could compile in your program's initialization code
a "sanity-checking" assert() or similar.

- David.Thompson1 at worldnet.att.net
 
B

Ben Pfaff

Jordan Abel said:
unfortunately, it appears that sizeof doesn't work in a preprocessor
directive - the question is, can I trust the maxes?

You can't trust the ranges or the sizes, actually, by my reading.
`long' and `int' could have the same size, range, and
representation, and it would still yield undefined behavior to
print one of them with the other format specifier. This is
because the description of the fprintf function states explicitly
what type arguments must be; it doesn't make any allowance for
equivalent representations.

However, I'd guess that using ranges would work on "normal"
implementations.
 
R

Richard Bos

Keith Thompson said:
Looks like someone has:

#include <stdlib.h>

/* Allocate space for an array with 10 elements of type int */
/* C++ needs a cast, C strongly discourages it */
int *ptr = malloc(sizeof *ptr * 10);

Anyone taking bets on how long before it's changed back?

Richard
 
F

Flash Gordon

Richard said:
Anyone taking bets on how long before it's changed back?

Well, when I looked yesterday the comment had been removed, but the code
was still the same. I changed the exit(1) to exit(EXIT_FAILURE) for them.
 
J

Jordan Abel

You can't trust the ranges or the sizes, actually, by my reading.
`long' and `int' could have the same size, range, and
representation, and it would still yield undefined behavior to
print one of them with the other format specifier.

As a matter of practice, though, if they both have the same range, and
size_t has the same range as both, size_t is more likely to be unsigned
int than unsigned long. [and, of course, if size_t is NARROWER than int,
you can use int, because it will be promoted]
 
B

Ben Pfaff

Jordan Abel said:
As a matter of practice, though, if they both have the same range, and
size_t has the same range as both, size_t is more likely to be unsigned
int than unsigned long. [...]

I've seen both `unsigned int' and `unsigned long' as size_t when
GCC is configured in different ways. I wouldn't want to depend
on either.
 
B

Ben Pfaff

Jordan Abel said:
As a matter of practice, though, if they both have the same range, and
size_t has the same range as both, size_t is more likely to be unsigned
int than unsigned long. [...]

I've seen both `unsigned int' and `unsigned long' as size_t when
GCC is configured in different ways on systems where those types
are identical, so I wouldn't want to assume that either one is
size_t.
 

Ask a Question

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

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

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top