dynamically allocate array variable of type LPWSTR

T

Trups

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
 
U

Ulrich Eckhardt

Trups said:
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
 
J

John Bode

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 */
}
 
K

Keith Thompson

Malcolm McLean said:
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, but it can easily by

employees->bonuslist[employees->Nlists];


Sure, but how often does that happen in practice?
 
C

Chris Dollin

blargg said:
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
 
V

vippstar

Keith Thompson said:
(e-mail address removed) (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 ->bar->baz [j]->boo [k]->blarg =
malloc( n * sizeof *foo ->bar->baz [j]->boo [k]->blarg );

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

foo ->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 ->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.
 
K

Keith Thompson

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.
 
B

Ben Bacarisse

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);
 
J

Joachim Schmitz

blargg said:
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
 
C

CBFalconer

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.

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?
 
N

Nick Keighley

     ^^^^^^^^^^
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?".

design problem 1. Why are the two a long way apart?


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.  [...]
     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. :)

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!
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top