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

dynamically allocate array variable of type LPWSTR

P: n/a
HI,

I want to dynamically allocate array variable of type LPWSTR.
Code looks like this...
main() {
LPWSTR *wstr;
int count = Foo (wstr);
for (int i = 0; i < count; i++)
//print each element;

}
int Foo(LPWSTR *wstr)
{
int count = 0;
while (!done){
//Here I need to allocate "wstr" one element by one element.
How
to do that?
// I don't know the count
count ++;
}

Where should I do delete?
Thanks
Trupti


Oct 31 '08 #1
Share this Question
Share on Google+
28 Replies


P: n/a
Trups wrote:
I want to dynamically allocate array variable of type LPWSTR.
Two things here:
1. LPWSTR is not a standard type but part of the win32 API.
2. LPWSTR is a pointer type, hence the 'P'. In fact it's a typedef for
wchar_t*.
Code looks like this...
main() {
Well, check the FAQ on this one.
LPWSTR *wstr;
int count = Foo (wstr);
You are passing the value of an uninitialised variable to a function. If you
want the function to init the variable, you need to pass its address.
int Foo(LPWSTR *wstr)
{
int count = 0;
while (!done){
//Here I need to allocate "wstr" one element by one element.
How
to do that?
// I don't know the count
count ++;
}
This looks as if you wanted to allocate an array of wchar_t strings.
However, I have actually no clue what it is that you really want.
Where should I do delete?
'delete' is a C++ thing, in C you would use malloc() and free().

Sorry, but there is too little to start with. I would suggest you get a good
book or some other tutorial that introduces you step by step to C. If
you're not familiar with programming at all, I would further suggest using
a language with less pitfalls, like e.g. Python.

Uli

Oct 31 '08 #2

P: n/a

"Trups" <Sa***********@gmail.comwrote in message news:
>
I want to dynamically allocate array variable of type LPWSTR.
Code looks like this...
main() {
LPWSTR *wstr;
int count = Foo (wstr);
for (int i = 0; i < count; i++)
//print each element;

}
int Foo(LPWSTR *wstr)
{
int count = 0;
while (!done){
//Here I need to allocate "wstr" one element by one element.
How
to do that?
// I don't know the count
count ++;
}

Where should I do delete?
Make sure you genuinely want a pointer to an LPWSTR. The LP is Microsoft's
way of indicating that the type is already a pointer.
However pointers to pointers are often useful. You use them for a list of
strings, for example.

In C arrays decay into pointers when you pass them to functions. Pointers
contain no size information. So you need to pass the buffer size separately.

There is no point passing an uninitialised pointer to a fucntion. C is call
by value, so you are just passing garbage.

I can't determine exactly what you want to do from your code. However it
looks like

int Foo(LPWSTR *ptr, int N)
{
int i;

for(i=0;i<N;i++)
ptr[i]= malloc(M * sizeof(WSTR));
}

where WSTR is whatever an LPWSTR points to, M is the number of them you want
in your array.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 31 '08 #3

P: n/a
Malcolm McLean wrote:
[...]
int Foo(LPWSTR *ptr, int N)
{
int i;

for(i=0;i<N;i++)
ptr[i]= malloc(M * sizeof(WSTR));
}

where WSTR is whatever an LPWSTR points to, M is the number of them you want
in your array.
Here's how you allocate without having to know the type of the object
pointed to:

ptr[i] = malloc(M * sizeof *ptr[i]);

It's a good practice to make a habit of, because it removes a point of
redundancy and thus a point of possible inconsistency.
Nov 1 '08 #4

P: n/a
blargg said:
Malcolm McLean wrote:
[...]
>int Foo(LPWSTR *ptr, int N)
{
int i;

for(i=0;i<N;i++)
ptr[i]= malloc(M * sizeof(WSTR));
}

where WSTR is whatever an LPWSTR points to, M is the number of them you
want in your array.

Here's how you allocate without having to know the type of the object
pointed to:

ptr[i] = malloc(M * sizeof *ptr[i]);

It's a good practice to make a habit of, because it removes a point of
redundancy and thus a point of possible inconsistency.

You are, of course, correct; in general, for p of any object type, the
template p = malloc(n * sizeof *p) is superior. But Malcolm has been
posting here for several years at least. The probability that he does not
already know this is vanishingly small. I conclude that he disagrees with
the rationale. I have no idea why he would disagree, but Malcolm often has
rather off-the-wall ideas about programming, so it wouldn't surprise me in
the slightest if his views on malloc are strange too.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 1 '08 #5

P: n/a
blargg said:
Malcolm McLean wrote:
[...]
>int Foo(LPWSTR *ptr, int N)
{
int i;

for(i=0;i<N;i++)
ptr[i]= malloc(M * sizeof(WSTR));
}

where WSTR is whatever an LPWSTR points to, M is the number of them you
want in your array.

Here's how you allocate without having to know the type of the object
pointed to:

ptr[i] = malloc(M * sizeof *ptr[i]);

It's a good practice to make a habit of, because it removes a point of
redundancy and thus a point of possible inconsistency.

You are, of course, correct; in general, for p of any object type, the
template p = malloc(n * sizeof *p) is superior. But Malcolm has been
posting here for several years at least. The probability that he does not
already know this is vanishingly small. I conclude that he disagrees with
the rationale. I have no idea why he would disagree, but Malcolm often has
rather off-the-wall ideas about programming, so it wouldn't surprise me in
the slightest if his views on malloc are strange too.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 1 '08 #6

P: n/a
On Oct 31, 9:07 am, Trups <Samant.Tru...@gmail.comwrote:
HI,

I want to dynamically allocate array variable of type LPWSTR.
Code looks like this...

main() {
LPWSTR *wstr;
int count = Foo (wstr);
for (int i = 0; i < count; i++)
//print each element;

}

int Foo(LPWSTR *wstr)
{
int count = 0;
while (!done){
//Here I need to allocate "wstr" one element by one element.
How
to do that?
// I don't know the count
count ++;
}

Where should I do delete?

Thanks
Trupti
The general procedure for dynamically allocating an N-element array of
any type T is

T *array = malloc(sizeof *array * numberOfElements);

That's if you know the number of elements to allocate ahead of time.
If you're allocating the array one element at a time, the procedure is
a little more complicated:

T *array = NULL, *tmp;
size_t arraySize = 0;
int done = 0;

/*
** Continue allocating elements until some condition is true
*/
while (!done)
{
/*
** if realloc cannot extend the array, it will return NULL
*/
tmp = realloc(array, sizeof *array * arraySize + 1);
if (!tmp)
{
/* realloc failed, handle error */
}
else
{
array = tmp;
arraySize++;
}

/* check if done */
}
Nov 2 '08 #7

P: n/a
"Richard Heathfield" <rj*@see.sig.invalidwrote in message news
blargg said:
>Malcolm McLean wrote:
[...]
>>int Foo(LPWSTR *ptr, int N)
{
int i;

for(i=0;i<N;i++)
ptr[i]= malloc(M * sizeof(WSTR));
}

where WSTR is whatever an LPWSTR points to, M is the number of them you
want in your array.

Here's how you allocate without having to know the type of the object
pointed to:

ptr[i] = malloc(M * sizeof *ptr[i]);

It's a good practice to make a habit of, because it removes a point of
redundancy and thus a point of possible inconsistency.


You are, of course, correct; in general, for p of any object type, the
template p = malloc(n * sizeof *p) is superior. But Malcolm has been
posting here for several years at least. The probability that he does not
already know this is vanishingly small. I conclude that he disagrees with
the rationale. I have no idea why he would disagree, but Malcolm often has
rather off-the-wall ideas about programming, so it wouldn't surprise me in
the slightest if his views on malloc are strange too.

Firstly, for pedagogical reasons I think the pointer dereference that isn't
really is a source of confusion. It is easier to think of sizeof() being
applied to a type.

My other objection is that the pointer in which the return address of
malloc() is stored can have a rather long identifier. Here it is only
ptr[i], but it can easily by

employees->bonuslist[employees->Nlists];
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Nov 2 '08 #8

P: n/a
In article <9f******************************@bt.com>,
"Malcolm McLean" <re*******@btinternet.comwrote:
"Richard Heathfield" <rj*@see.sig.invalidwrote in message news
blargg said:
Malcolm McLean wrote:
[...]
int Foo(LPWSTR *ptr, int N)
{
int i;

for(i=0;i<N;i++)
ptr[i]= malloc(M * sizeof(WSTR));
}

where WSTR is whatever an LPWSTR points to, M is the number of them you
want in your array.

Here's how you allocate without having to know the type of the object
pointed to:

ptr[i] = malloc(M * sizeof *ptr[i]);

It's a good practice to make a habit of, because it removes a point of
redundancy and thus a point of possible inconsistency.
You are, of course, correct; in general, for p of any object type, the
template p = malloc(n * sizeof *p) is superior. But Malcolm has been
posting here for several years at least. The probability that he does not
already know this is vanishingly small. I conclude that he disagrees with
the rationale. I have no idea why he would disagree, but Malcolm often has
rather off-the-wall ideas about programming, so it wouldn't surprise me in
the slightest if his views on malloc are strange too.

Firstly, for pedagogical reasons I think the pointer dereference that isn't
really is a source of confusion. It is easier to think of sizeof() being
applied to a type.
I somewhat agree. On the other hand, by avoiding using sizeof object
early on, the student isn't given an opportunity to become familiar.
My other objection is that the pointer in which the return address of
malloc() is stored can have a rather long identifier. Here it is only
ptr[i], but it can easily by

employees->bonuslist[employees->Nlists];
employees->bonuslist[employees->Nlists] =
malloc( sizeof *employees->bonuslist[0] );
Nov 2 '08 #9

P: n/a
"blargg" <bl********@gishpuppy.comwrote in message news:
In article <9f******************************@bt.com>,
"Malcolm McLean" <re*******@btinternet.comwrote:
>"Richard Heathfield" <rj*@see.sig.invalidwrote in message news
blargg said:

Malcolm McLean wrote:
[...]
int Foo(LPWSTR *ptr, int N)
{
int i;

for(i=0;i<N;i++)
ptr[i]= malloc(M * sizeof(WSTR));
}

where WSTR is whatever an LPWSTR points to, M is the number of them
you
want in your array.

Here's how you allocate without having to know the type of the object
pointed to:

ptr[i] = malloc(M * sizeof *ptr[i]);

It's a good practice to make a habit of, because it removes a point of
redundancy and thus a point of possible inconsistency.

You are, of course, correct; in general, for p of any object type, the
template p = malloc(n * sizeof *p) is superior. But Malcolm has been
posting here for several years at least. The probability that he does
not
already know this is vanishingly small. I conclude that he disagrees
with
the rationale. I have no idea why he would disagree, but Malcolm often
has
rather off-the-wall ideas about programming, so it wouldn't surprise me
in
the slightest if his views on malloc are strange too.

Firstly, for pedagogical reasons I think the pointer dereference that
isn't
really is a source of confusion. It is easier to think of sizeof() being
applied to a type.

I somewhat agree. On the other hand, by avoiding using sizeof object
early on, the student isn't given an opportunity to become familiar.
>My other objection is that the pointer in which the return address of
malloc() is stored can have a rather long identifier. Here it is only
ptr[i], but it can easily by

employees->bonuslist[employees->Nlists];

employees->bonuslist[employees->Nlists] =
malloc( sizeof *employees->bonuslist[0] );
That's not a bad idea.
Now you're breaking the symmetry that the sizeof the object that is pointed
to by the return of malloc() is taken.
In fact you'd need more than one of them. So make that

malloc(employees->Nbonuses * sizeof *employees->bonuslist[0]);

and of course the asterisk is being used in two different contexts.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Nov 2 '08 #10

P: n/a
"Malcolm McLean" <re*******@btinternet.comwrites:
[...]
Firstly, for pedagogical reasons I think the pointer dereference that
isn't really is a source of confusion. It is easier to think of
sizeof() being applied to a type.
For pedagogical reasons you can always *tell* people that the operand
of sizeof isn't evaluated.
My other objection is that the pointer in which the return address of
malloc() is stored can have a rather long identifier. Here it is only
ptr[i], but it can easily by

employees->bonuslist[employees->Nlists];
Sure, but how often does that happen in practice?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 2 '08 #11

P: n/a
Keith Thompson said:
"Malcolm McLean" <re*******@btinternet.comwrites:
[...]
>Firstly, for pedagogical reasons I think the pointer dereference that
isn't really is a source of confusion. It is easier to think of
sizeof() being applied to a type.

For pedagogical reasons you can always *tell* people that the operand
of sizeof isn't evaluated.
Yes. It's something they need to know, and not just for this reason.
>
>My other objection is that the pointer in which the return address of
malloc() is stored can have a rather long identifier. Here it is only
ptr[i], but it can easily by

employees->bonuslist[employees->Nlists];

Sure, but how often does that happen in practice?
You'd be amazed. It seems to happen to me rather often. Even so, I still
think the advantages of the pattern easily outweigh this disadvantage.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 2 '08 #12

P: n/a
In article <74******************************@bt.com>, "Malcolm McLean"
<re*******@btinternet.comwrote:
"blargg" <bl********@gishpuppy.comwrote in message news:
In article <9f******************************@bt.com>,
"Malcolm McLean" <re*******@btinternet.comwrote:
[...]
My other objection is that the pointer in which the return address of
malloc() is stored can have a rather long identifier. Here it is only
ptr[i], but it can easily by

employees->bonuslist[employees->Nlists];
employees->bonuslist[employees->Nlists] =
malloc( sizeof *employees->bonuslist[0] );
That's not a bad idea.
Now you're breaking the symmetry that the sizeof the object that is pointed
to by the return of malloc() is taken.
In fact you'd need more than one of them. So make that

malloc(employees->Nbonuses * sizeof *employees->bonuslist[0]);

and of course the asterisk is being used in two different contexts.
malloc(employees->Nbonuses * sizeof employees->bonuslist[0][0]);

And while we're on the topic, using a cast is actually a GOOD idea if one
is naming the type in sizeof, since it will catch the error of the
destination type being different than you expect:

long* p = malloc( n * sizeof (int) ); // oops, but no error
long* p = (int*) malloc( n * sizeof (int) ); // compiler catches it
Nov 3 '08 #13

P: n/a
blargg said:

<snip>
And while we're on the topic, using a cast is actually a GOOD idea if one
is naming the type in sizeof, since it will catch the error of the
destination type being different than you expect:
If you're using a pointer type other than the one you intended to use,
presumably there'll be plenty of cases elsewhere in the code where you use
the type you *did* intend to use, in which case there should be no
shortage of diagnostic messages. And assuming that, by adding a cast, you
can catch a type error for a call to a function returning void *, is a
poor strategy...
>
long* p = malloc( n * sizeof (int) ); // oops, but no error
long* p = (int*) malloc( n * sizeof (int) ); // compiler catches it
long *p = (long *)malloc(n * sizeof (int)); /* oops, no error */

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 3 '08 #14

P: n/a
bl********@gishpuppy.com (blargg) writes:
[...]
And while we're on the topic, using a cast is actually a GOOD idea if one
is naming the type in sizeof, since it will catch the error of the
destination type being different than you expect:

long* p = malloc( n * sizeof (int) ); // oops, but no error
long* p = (int*) malloc( n * sizeof (int) ); // compiler catches it
long *p = malloc(n * sizeof *p); // no error for the compiler to catch

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 3 '08 #15

P: n/a
In article <ln************@nuthaus.mib.org>, Keith Thompson
<ks***@mib.orgwrote:
bl********@gishpuppy.com (blargg) writes:
[...]
And while we're on the topic, using a cast is actually a GOOD idea if one
is naming the type in sizeof, since it will catch the error of the
destination type being different than you expect:

long* p = malloc( n * sizeof (int) ); // oops, but no error
long* p = (int*) malloc( n * sizeof (int) ); // compiler catches it

long *p = malloc(n * sizeof *p); // no error for the compiler to catch
You snipped the context. This is going in circles now :)

My point was that if the expression being assigned to is more unweildy
than the type name itself, one might choose to use sizeof(type) rather
than sizeof *expr_being_assigned_to. In that case, casting the result of
malloc to type* ensures that the type being assigned to is compatible with
the type you're allocating for. Thus, if you had

foo [i]->bar->baz [j]->boo [k]->blarg =
malloc( n * sizeof *foo [i]->bar->baz [j]->boo [k]->blarg );

you might prefer to just name the type of blarg, let's say int* here

foo [i]->bar->baz [j]->boo [k]->blarg = malloc( n * sizeof (int) );

but if it really was long* , you'd have an undiagnosed error. But if you
also cast the result

foo [i]->bar->baz [j]->boo [k]->blarg = (int*) malloc( n * sizeof (int) );

you'd get a compile error if it wasn't an int*. Yes, you could mistakenly
cast it to a long* and use sizeof(int), introducing an error anyway, but
the lesser distance between the inconsistencies is such that it can be
easier to track down. It's only a few characters, while the distance
between a mismatch in the second example that lacks the cast might be
hundreds of lines, or span files.
Nov 3 '08 #16

P: n/a
blargg wrote:
In article <ln************@nuthaus.mib.org>, Keith Thompson
<ks***@mib.orgwrote:
>bl********@gishpuppy.com (blargg) writes:
[...]
And while we're on the topic, using a cast is actually a GOOD idea if one
is naming the type in sizeof, since it will catch the error of the
destination type being different than you expect:

long* p = malloc( n * sizeof (int) ); // oops, but no error
long* p = (int*) malloc( n * sizeof (int) ); // compiler catches it

long *p = malloc(n * sizeof *p); // no error for the compiler to catch

You snipped the context. This is going in circles now :)

My point was that if the expression being assigned to is more unweildy
than the type name itself, one might choose
.... to fix the unweildy expression.

For what it's worth [1], I've never had an "unweildy" expression as the
target of a mallocation, probably because most of my mallocations end up
in create-me-this-heap-object functions.

[1] Auction!

--
'Don't be afraid: /Electra City/
there will be minimal destruction.' - Panic Room

Hewlett-Packard Limited registered office: Cain Road, Bracknell,
registered no: 690597 England Berks RG12 1HN

Nov 3 '08 #17

P: n/a
On Nov 3, 1:17 pm, blargg....@gishpuppy.com (blargg) wrote:
In article <ln63n5xo05....@nuthaus.mib.org>, Keith Thompson

<ks...@mib.orgwrote:
blargg....@gishpuppy.com (blargg) writes:
[...]
And while we're on the topic, using a cast is actually a GOOD idea if one
is naming the type in sizeof, since it will catch the error of the
destination type being different than you expect:
long* p = malloc( n * sizeof (int) ); // oops, but no error
long* p = (int*) malloc( n * sizeof (int) ); // compiler catches it
What about long *p = (long *)malloc(n * sizeof (int)); ?
Your method is not offering anything.
long *p = malloc(n * sizeof *p); // no error for the compiler to catch

You snipped the context. This is going in circles now :)

My point was that if the expression being assigned to is more unweildy
than the type name itself, one might choose to use sizeof(type) rather
than sizeof *expr_being_assigned_to. In that case, casting the result of
malloc to type* ensures that the type being assigned to is compatible with
the type you're allocating for. Thus, if you had

foo [i]->bar->baz [j]->boo [k]->blarg =
malloc( n * sizeof *foo [i]->bar->baz [j]->boo [k]->blarg );

you might prefer to just name the type of blarg, let's say int* here

foo [i]->bar->baz [j]->boo [k]->blarg = malloc( n * sizeof (int) );

but if it really was long* , you'd have an undiagnosed error. But if you
also cast the result

foo [i]->bar->baz [j]->boo [k]->blarg = (int*) malloc( n * sizeof (int) );

you'd get a compile error if it wasn't an int*. Yes, you could mistakenly
cast it to a long* and use sizeof(int), introducing an error anyway, but
the lesser distance between the inconsistencies is such that it can be
easier to track down. It's only a few characters, while the distance
between a mismatch in the second example that lacks the cast might be
hundreds of lines, or span files.

If you're dealing with that many levels of dereferencing, it's quite
possible that your code needs rewriting.
Nov 3 '08 #18

P: n/a
bl********@gishpuppy.com (blargg) writes:
In article <ln************@nuthaus.mib.org>, Keith Thompson
<ks***@mib.orgwrote:
>bl********@gishpuppy.com (blargg) writes:
[...]
And while we're on the topic, using a cast is actually a GOOD idea if one
is naming the type in sizeof, since it will catch the error of the
destination type being different than you expect:

long* p = malloc( n * sizeof (int) ); // oops, but no error
long* p = (int*) malloc( n * sizeof (int) ); // compiler catches it

long *p = malloc(n * sizeof *p); // no error for the compiler to catch

You snipped the context. This is going in circles now :)

My point was that if the expression being assigned to is more unweildy
than the type name itself, one might choose to use sizeof(type) rather
than sizeof *expr_being_assigned_to. In that case, casting the result of
malloc to type* ensures that the type being assigned to is compatible with
the type you're allocating for.
[...]

And *my* point is that, even if the expression is unwieldy, using the
type name is not the answer. Either go ahead and use the expression
anyway, or use a simpler expression.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 3 '08 #19

P: n/a
bl********@gishpuppy.com (blargg) writes:
In article <ln************@nuthaus.mib.org>, Keith Thompson
<ks***@mib.orgwrote:
>bl********@gishpuppy.com (blargg) writes:
[...]
And while we're on the topic, using a cast is actually a GOOD idea if one
is naming the type in sizeof, since it will catch the error of the
destination type being different than you expect:

long* p = malloc( n * sizeof (int) ); // oops, but no error
long* p = (int*) malloc( n * sizeof (int) ); // compiler catches it

long *p = malloc(n * sizeof *p); // no error for the compiler to catch

You snipped the context. This is going in circles now :)
I'd like to unwind some of them! I think there are two problems here
and they should be separated. The first is allocating the right
sized memory using malloc (et al.) and the second is an odd problem of
having the wrong declaration for a pointer variable.

For the first, the c.l.c idiom is unequivocally the best solution and
having an unwieldy expression in the assignment simply suggest that
other simplification is required -- not that the idiom is at fault.

For the second, a cast on malloc might catch one instance but surely
there will be others if the declaration is wrong? If you find that
your code (or any code base) seems to have this sort of error in it
then you need another solution. One possibility would be use a type
assertion which can be put anywhere, though of course, it could be
combined with a malloc call:

#define PTR_TYPE_ASSERT(type, var) do { type (*t_) = (var); } while (0)

p = malloc(n * sizeof *p);
PTR_TYPE_ASSERT(long, p);

--
Ben.
Nov 3 '08 #20

P: n/a
In article <W_******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
blargg said:

<snip>
And while we're on the topic, using a cast is actually a GOOD idea if one
is naming the type in sizeof, since it will catch the error of the
destination type being different than you expect:

If you're using a pointer type other than the one you intended to use,
presumably there'll be plenty of cases elsewhere in the code where you use
the type you *did* intend to use, in which case there should be no
shortage of diagnostic messages. And assuming that, by adding a cast, you
can catch a type error for a call to a function returning void *, is a
poor strategy...

long* p = malloc( n * sizeof (int) ); // oops, but no error
long* p = (int*) malloc( n * sizeof (int) ); // compiler catches it

long *p = (long *)malloc(n * sizeof (int)); /* oops, no error */
Below is the essence of the issue raised in the thread, where the
expression being assigned to is complex and one would rather not repeat
it within the malloc, so ignore the fact that one would much prefer
malloc(sizeof *p) if this were the actual code.

Of the two, which error is more likely to be caught by the programmer?

long* p;

// way later in file
p = malloc( sizeof (int) ); // 1
p = (long*) malloc( sizeof (int) ); // 2

I'd say that 2 is more likely to be caught by the programmer. That was
my only point; if it's a choice between these two, I'd prefer the
second, because the programmer can more easily verify that he did the
cast correctly, and the compiler can then verify the assignment. In the
first, the compiler can't catch anything, and the programmer has to
compare the type of p, wherever it's defined, to the type in malloc. And
as a reminder, see the disclaimer in the previous paragraph.
Nov 3 '08 #21

P: n/a
blargg said:

<snip>
Below is the essence of the issue raised in the thread, where the
expression being assigned to is complex and one would rather not repeat
it within the malloc, so ignore the fact that one would much prefer
malloc(sizeof *p) if this were the actual code.
Sorry, but I find it impossible to ignore the significantly superior
solution in favour of a couple of broken ones.
Of the two, which error is more likely to be caught by the programmer?

long* p;

// way later in file
p = malloc( sizeof (int) ); // 1
p = (long*) malloc( sizeof (int) ); // 2
You've provided two inferior idioms, and asked which is better (for a
certain value of "better", which you rightly define). My answer is: forget
them both, and use the *best* idiom.
I'd say that 2 is more likely to be caught by the programmer. That was
my only point; if it's a choice between these two, I'd prefer the
second,
But that's a false dichotomy. There is another choice, and it's a better
one than either of those (which, incidentally, appear equally broken to
me).

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 3 '08 #22

P: n/a
blargg wrote:
In article <W_******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>blargg said:

<snip>
>>And while we're on the topic, using a cast is actually a GOOD idea
if one is naming the type in sizeof, since it will catch the error
of the destination type being different than you expect:

If you're using a pointer type other than the one you intended to
use, presumably there'll be plenty of cases elsewhere in the code
where you use the type you *did* intend to use, in which case there
should be no shortage of diagnostic messages. And assuming that, by
adding a cast, you can catch a type error for a call to a function
returning void *, is a poor strategy...
>>>
long* p = malloc( n * sizeof (int) ); // oops, but no error
long* p = (int*) malloc( n * sizeof (int) ); // compiler
catches it

long *p = (long *)malloc(n * sizeof (int)); /* oops, no error */

Below is the essence of the issue raised in the thread, where the
expression being assigned to is complex and one would rather not
repeat it within the malloc, so ignore the fact that one would much
prefer malloc(sizeof *p) if this were the actual code.

Of the two, which error is more likely to be caught by the programmer?

long* p;

// way later in file
p = malloc( sizeof (int) ); // 1
p = (long*) malloc( sizeof (int) ); // 2

I'd say that 2 is more likely to be caught by the programmer. That was
my only point; if it's a choice between these two, I'd prefer the
second, because the programmer can more easily verify that he did the
cast correctly, and the compiler can then verify the assignment. In
the first, the compiler can't catch anything, and the programmer has
to compare the type of p, wherever it's defined, to the type in
malloc. And as a reminder, see the disclaimer in the previous
paragraph.
What if, instead of your 'better' version, some programmer writes
p = (int*) malloc( sizeof (int) ); // 3
Leaves him/her in the false assumption that everything is fine, right?

What if that programmer forgot to provide a prototype for malloc()?
The compiler won't be able to warn him/her about it.

What if int was the right choce at one time, but later got changed to long?

So your solution does cause more harm than it has benefits. A plain and
simple
p = malloc( sizeof *p ); // 4
doesn't have any of these problems. The only problem that it does have, is
that you can't use a C++ Compiler on it. But then again in C++ you should be
using C++ means of allocation memore, i.e. 'new' rather that C methods, so
even that problen is not a problem but a chance to modify the code to do it
right rather than to carry over some legacy code.

Bye, Jojo
Nov 3 '08 #23

P: n/a
Joachim Schmitz wrote:
blargg wrote:
>[...]
Of the two, which error is more likely to be caught by the programmer?

long* p;

// way later in file
p = malloc( sizeof (int) ); // 1
p = (long*) malloc( sizeof (int) ); // 2

I'd say that 2 is more likely to be caught by the programmer. That was
my only point; if it's a choice between these two, I'd prefer the
second, because the programmer can more easily verify that he did the
cast correctly, and the compiler can then verify the assignment. [...]

What if, instead of your 'better' version, some programmer writes
p = (int*) malloc( sizeof (int) ); // 3
Leaves him/her in the false assumption that everything is fine, right?
Not after the compiler issues the mandatory diagnostic message ...
What if that programmer forgot to provide a prototype for malloc()?
The compiler won't be able to warn him/her about it.
Many C90 compilers will; all C99 compilers must.
What if int was the right choce at one time, but later got changed to long?

So your solution does cause more harm than it has benefits. A plain and
simple
p = malloc( sizeof *p ); // 4
doesn't have any of these problems. The only problem that it does have, is
that you can't use a C++ Compiler on it. [...]
blargg explicitly acknowledges this form as superior to both
his alternatives, but points out that it does in fact have a problem:
What, he askes, if `p' is more complicated?

findRoot(muggle,buggle)->branch[sublevel++].
recorded_maxima->thresholds
= malloc(sizeof *findRoot(muggle,buggle)->
branch[sublevel++].recorded_maxima->thresholds);

Yes, you can pretty easily copy-and-paste to get the thing right in
the first place, but you wind up with a mess that a future programmer
will have trouble reading and verifying. Plus, you've got that scary-
looking side-effect that seems to occur twice ...

Personally, I don't find blargg's problem all that troublesome.
Maybe it's just style, but the left-hand sides of my mallocations
don't tend to be quite that involved; I'd be tempted to decompose
them anyhow, as in

Root root = findRoot(muggle,buggle);
Maxima maxima = root->branch[sublevel++].recorded_maxima;
maxima->thresholds = malloc(sizeof *maxima->thresholds);

.... on the grounds that this would improve readability even if the
mallocation were a printf or some such.

--
Er*********@sun.com
Nov 3 '08 #24

P: n/a
blargg wrote:
>
.... snip ...
>
Below is the essence of the issue raised in the thread, where the
expression being assigned to is complex and one would rather not
repeat it within the malloc, so ignore the fact that one would
much prefer malloc(sizeof *p) if this were the actual code.

Of the two, which error is more likely to be caught by the
programmer?

long* p;

// way later in file
p = malloc( sizeof (int) ); // 1
p = (long*) malloc( sizeof (int) ); // 2

I'd say that 2 is more likely to be caught by the programmer.
That was my only point; if it's a choice between these two, I'd
prefer the second, because the programmer can more easily verify
that he did the cast correctly, and the compiler can then verify
the assignment. In the first, the compiler can't catch anything,
and the programmer has to compare the type of p, wherever it's
defined, to the type in malloc. And as a reminder, see the
disclaimer in the previous paragraph.
However, using the generally approved technique:

long *p;
...
/* anywhere later in file */
p = malloc(N * sizeof *p);

(and you can replace "N *" with nothing for N == 1) is proof
against errors anywhere. Why use anything poorer?

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Nov 3 '08 #25

P: n/a
In article <1225737875.108099@news1nwk>, Eric Sosman <Er*********@sun.com>
wrote:
Joachim Schmitz wrote:
blargg wrote:
[...]
Of the two, which error is more likely to be caught by the programmer?
^^^^^^^^^^
Easy to miss this part, or disregard it, I guess. :(
long* p;

// way later in file
p = malloc( sizeof (int) ); // 1
p = (long*) malloc( sizeof (int) ); // 2

I'd say that 2 is more likely to be caught by the programmer. That was
my only point; if it's a choice between these two, I'd prefer the
second, because the programmer can more easily verify that he did the
cast correctly, and the compiler can then verify the assignment. [...]
What if, instead of your 'better' version, some programmer writes
p = (int*) malloc( sizeof (int) ); // 3
Leaves him/her in the false assumption that everything is fine, right?

Not after the compiler issues the mandatory diagnostic message ...
What if that programmer forgot to provide a prototype for malloc()?
The compiler won't be able to warn him/her about it.

Many C90 compilers will; all C99 compilers must.
What if int was the right choce at one time, but later got changed to long?

So your solution does cause more harm than it has benefits. A plain and
simple
p = malloc( sizeof *p ); // 4
doesn't have any of these problems. The only problem that it does have, is
that you can't use a C++ Compiler on it. [...]

blargg explicitly acknowledges this form as superior to both
his alternatives, but points out that it does in fact have a problem:
What, he askes, if `p' is more complicated?
Thank you. At least someone is reading my entire posts before responding. :)

[...]
Personally, I don't find blargg's problem all that troublesome.
Yes, it's not common for it to be complex, but someone brought it up so I
figured I'd try to address it. Personally, my solution is to use C++.
findRoot(muggle,buggle)->branch[sublevel++].
recorded_maxima->thresholds
= malloc(sizeof *findRoot(muggle,buggle)->
branch[sublevel++].recorded_maxima->thresholds);
Last comment on this subject from me. I suppose one could write a macro to
encapsulate it:

#define SMART_MALLOC( out, n ) \
out = malloc( (n) * sizeof *(out) )

SMART_MALLOC( findRoot(muggle,buggle)->branch[sublevel++].
recorded_maxima->thresholds, 1 );
Nov 4 '08 #26

P: n/a
Richard Heathfield wrote:
blargg said:
<snip>
Below is the essence of the issue raised in the thread, where the
expression being assigned to is complex and one would rather not repeat
it within the malloc, so ignore the fact that one would much prefer
malloc(sizeof *p) if this were the actual code.

Sorry, but I find it impossible to ignore the significantly superior
solution in favour of a couple of broken ones.
Too bad; I find value in sometimes exploring and analyzing things without
regard to their immediate value. I also find that separating things into
absolute good/bad is very limiting, because there are always situations
where the "good" is worse than the "bad". I prefer to let the situation
determine the relative value of different approaches, and choose the best
approach for each particular situation. In this situation, as I described
at the start, the only question was which was better of the two shown. I
completely disregarded the merit of either as compared to other
alternatives. I guess it's a sort of modularity-of-analysis, rather than
trying to do everything at once.
Of the two, which error is more likely to be caught by the programmer?

long* p;

// way later in file
p = malloc( sizeof (int) ); // 1
p = (long*) malloc( sizeof (int) ); // 2
I'd say that 2 is more likely to be caught by the programmer. That was
my only point; if it's a choice between these two, I'd prefer the
second,

But that's a false dichotomy. There is another choice, and it's a better
one than either of those (which, incidentally, appear equally broken to
me).
I never said those were the only choices; I simply wanted to show that
among those, one was better. The reasoning behind it was the key point.
Nov 4 '08 #27

P: n/a
On 4 Nov, 04:14, blargg....@gishpuppy.com (blargg) wrote:
In article <1225737875.108099@news1nwk>, Eric Sosman <Eric.Sos...@sun.com>
Joachim Schmitz wrote:
blargg wrote:
>Of the two, which error is more likely to be caught by the programmer?

* * *^^^^^^^^^^
Easy to miss this part, or disregard it, I guess. :(
upu are asking "which of two bad solutions should I pick instead of
using the good solution". Or "is it better to play russian roulette
with one bullet or two?".
>* *long* p;
>* *// way later in file
design problem 1. Why are the two a long way apart?

>* *p = malloc( sizeof (int) ); // 1
>* *p = (long*) malloc( sizeof (int) ); // 2
design problem 2. Simply use the clc recomended idiom.

p = malloc (sizeof *p);

it's even shorter in this case

>I'd say that 2 is more likely to be caught by the programmer. That was
>my only point; if it's a choice between these two, I'd prefer the
>second, because the programmer can more easily verify that he did the
>cast correctly, and the compiler can then verify the assignment. *[...]
<snip>
* * *blargg explicitly acknowledges this form as superior to both
his alternatives, but points out that it does in fact have a problem:
What, he askes, if `p' is more complicated?
use a variable

Thank you. At least someone is reading my entire posts before responding.:)
* * *Personally, I don't find blargg's problem all that troublesome.
I think he's straining at gnats

Yes, it's not common for it to be complex, but someone brought it up so I
figured I'd try to address it. Personally, my solution is to use C++.
I wouldn't be using malloc() with C++

* * * * findRoot(muggle,buggle)->branch[sublevel++].
* * * * * * recorded_maxima->thresholds
* * * * * * = malloc(sizeof *findRoot(muggle,buggle)->
* * * * * * * * * branch[sublevel++].recorded_maxima->thresholds);
long *thesholds;
thresholds = malloc (sizeof *thresholds);
findRoot (muggle, buggle)->branch [sublevel++].recorded_maxima-
>thresholds
= thresholds;
Last comment on this subject from me. I suppose one could write a macro to
encapsulate it:
yuk! (and that's before I read the macro)

>
* * #define SMART_MALLOC( out, n ) \
* * * * out = malloc( (n) * sizeof *(out) )
yup. I've written this macro. It's a bad idea.

* * SMART_MALLOC( findRoot(muggle,buggle)->branch[sublevel++].
* * * * * * recorded_maxima->thresholds, 1 )
[oops, possible over-keen snipping by me]

but still, yuk!
--
Nick Keighley

"That's right!" shouted Vroomfondel "we demand rigidly defined
areas of doubt and uncertainty!"

Nov 4 '08 #28

P: n/a
blargg said:
Richard Heathfield wrote:
>blargg said:
<snip>
Below is the essence of the issue raised in the thread, where the
expression being assigned to is complex and one would rather not
repeat it within the malloc, so ignore the fact that one would much
prefer malloc(sizeof *p) if this were the actual code.

Sorry, but I find it impossible to ignore the significantly superior
solution in favour of a couple of broken ones.

Too bad; I find value in sometimes exploring and analyzing things without
regard to their immediate value.
"What use is a new-born baby?" and all that. That's often a compelling
argument, but I don't think it really works here.
I also find that separating things into
absolute good/bad is very limiting, because there are always situations
where the "good" is worse than the "bad".
A pragmatic attitude - "whatever works!" - is good. But a pragmatic
attitude will, all else being equal, tend to favour a good solution over a
bad one, simply because it works better.
I prefer to let the situation
determine the relative value of different approaches, and choose the best
approach for each particular situation. In this situation, as I described
at the start, the only question was which was better of the two shown.
Then it was the wrong question. :-)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 4 '08 #29

This discussion thread is closed

Replies have been disabled for this discussion.