Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Struct pointer vs. struct array pointer (http://www.velocityreviews.com/forums/t957823-struct-pointer-vs-struct-array-pointer.html)

aleksa 02-20-2013 09:17 AM

Struct pointer vs. struct array pointer
 
Say I'm using a standard windows RECT structure...

RECT *prect;

// I can write
prect->left = 0;

// but I can also write
prect[-1].left = 0;
prect[0].left = 0;
prect[1].left = 0;

and the compiler won't complain...
So, what did I define in the first line, a pointer to ONE structure or
a pointer to an ARRAY of structures?

How can I define a pointer to an array?
I don't know in advance how many RECTs there will be in the array.

I'm asking because I can't make WinDbg (nor MSVC debuffer) to show
me the whole array of RECTs.

Thanks

Malcolm McLean 02-20-2013 09:59 AM

Re: Struct pointer vs. struct array pointer
 
On Wednesday, February 20, 2013 9:17:32 AM UTC, aleksa wrote:
> Say I'm using a standard windows RECT structure...
>
>
>
> RECT *prect;
>
>
> prect->left = 0;
>

As the code stands, prect is set to whatever random data was in the memory space assigned to it. So the second line sets a random memory location to zero. Usually the result will be a segmentation fault, but not always.

To fix this problem

RECT rect;
prect = ▭

but of course this us useless. Why not just write rect.left = 0 instead?

>
> How can I define a pointer to an array?
>
> I don't know in advance how many RECTs there will be in the array.
>
>

It bcoomes useful here

RECT rectarray[15];

rectarray, is to all intents and purposes, a constant pointer to a block of 15 RECTs.

So what if you don't know how many you'll need at compile time?

RECT *rectp = malloc( Nwanted * sizeof(RECT));

for(i=0;i<Nwanted;i++)
rectp[i].left = 0;

This creates Nwanted RECTs, and sets the left member of them all to zero.
Nwanted can be an input value.

--
Read malcolm's book, Basic Algorithms
http://www.malcolmmclean.site11.com/www


Sebastian Gesemann 02-20-2013 11:12 AM

Re: Struct pointer vs. struct array pointer
 
On Feb 20, 10:17*am, aleksa <aleks...@gmail.com> wrote:
> Say I'm using a standard windows RECT structure...
>
> RECT *prect;


I hope that you initialize this pointer to actually point to some RECT
object.

> // I can write
> prect->left = 0;
>
> // but I can also write
> prect[-1].left = 0;
> prect[0].left *= 0;
> prect[1].left *= 0;
>
> and the compiler won't complain...
> So, what did I define in the first line, a pointer to ONE structure or
> a pointer to an ARRAY of structures?


You defined prect to be a pointer to _a_ RECT object. However, nothing
stops you from initializing it to point to the first (or any, really)
element of a RECT array.

The syntax

prect[index]

is simply defined to be a short-cut for

*(prect+index)

So, you're just doing pointer arithmetics followed by dereferencing.
If your pointer were to point to the first element of an array, you
could access this first element by

*prect

or alternativly by

prect[0]

Accessing the other array elements, however, is much more convenient
with the latter syntax:

prect[42]

instead of

*(prect+42)

Since the elements of an array are stored contiguously, this kind of
pointer arithmetic is exactly what you need to access the other array
elements.

> How can I define a pointer to an array?


You can still use a variable of type RECT* to point to the first
element of an array and access the other elements via the subscript
operator. With respect to its type, it's still just a pointer to a
single RECT. Depending on who you talk to "pointer to an array" could
mean just that, a pointer that points to the first element of an
array. To other people "pointer to array" means that the pointee type
is an array type:

int (*p)[5] = ...;

which reads: p is a pointer to an array of 5 ints. So, there is some
potential for confusion there ...

Check out http://c-faq.com/aryptr/index.html for more details on this
subject. There are a couple of things that you should know including
array-to-pointer decay and the type transformations that are applied
on function parameter types.

> I don't know in advance how many RECTs there will be in the array.


Sounds like you're in need for some dynamic buffer implementation that
keeps track of its size and capacity and is able to grow if the
capacity limit is reached. Unfortunately this kind of data structure
is not part of the C standard library. Since I'm a C++ programmer who
can simply #include <vector> I can't give you any good advice on how
to proceed in pure C here. Rolling your own data structures is kind of
a PITA. Maybe you'll find a useful library for that. (GLib?)

> I'm asking because I can't make WinDbg (nor MSVC debuffer) to show
> me the whole array of RECTs.


That's because the type information of such a pointer doesn't really
tell the debugger whether it points to a single object or a subobject
of an array and how large this array is. You have to do this manually
somehow. A decent debugger should let you evaluate custom expressions
like yourpointer[3] so that it tells you what the 4th element of the
array looks like, for example.

James Kuyper 02-20-2013 11:22 AM

Re: Struct pointer vs. struct array pointer
 
On 02/20/2013 04:59 AM, Malcolm McLean wrote:
....
> RECT rectarray[15];
>
> rectarray, is to all intents and purposes, a constant pointer to a block of 15 RECTs.


Except, of course, for the purposes of being an operand of the sizeof or
unary & operators. It's not a pointer, it's an array. C makes it easy to
confuse arrays and pointers; you do aleksa a disservice by actively
promoting that confusion.
--
James Kuyper

aleksa 02-20-2013 12:30 PM

Re: Struct pointer vs. struct array pointer
 
On Wednesday, February 20, 2013 12:12:18 PM UTC+1, Sebastian Gesemann wrote:
> int (*p)[5] = ...;


Since my only concern here was how to view entire structure array
(or at least some of it) using WinDbg, maybe this is the best:

RECT (*prect2)[100];

now I can view the first 100 entries, which is more than enough.

Now, how do I assigne prect2 to point to the same memory as prect?

prect2 = prect;
prect2 = &prect[0];

both work and both give me the same error
"...differs in levels of indirection from..."

Ben Bacarisse 02-20-2013 12:48 PM

Re: Struct pointer vs. struct array pointer
 
aleksa <aleksazr@gmail.com> writes:

> On Wednesday, February 20, 2013 12:12:18 PM UTC+1, Sebastian Gesemann wrote:
>> int (*p)[5] = ...;

>
> Since my only concern here was how to view entire structure array
> (or at least some of it) using WinDbg, maybe this is the best:
>
> RECT (*prect2)[100];
>
> now I can view the first 100 entries, which is more than enough.


If the purpose is simply to view things in a debugger it seems excessive
to have to alter the source. Can't you use an expression in the
debugger? I.e. where you now say something like "print prect2" could
you not say "print *((*)[100])prect"?

> Now, how do I assigne prect2 to point to the same memory as prect?
>
> prect2 = prect;
> prect2 = &prect[0];
>
> both work and both give me the same error
> "...differs in levels of indirection from..."


prect2 = (void *)prect;

--
Ben.

James Kuyper 02-20-2013 01:29 PM

Re: Struct pointer vs. struct array pointer
 
On 02/20/2013 07:30 AM, aleksa wrote:
> On Wednesday, February 20, 2013 12:12:18 PM UTC+1, Sebastian Gesemann wrote:
>> int (*p)[5] = ...;

>
> Since my only concern here was how to view entire structure array
> (or at least some of it) using WinDbg, maybe this is the best:
>
> RECT (*prect2)[100];
>
> now I can view the first 100 entries, which is more than enough.
>
> Now, how do I assigne prect2 to point to the same memory as prect?
>
> prect2 = prect;
> prect2 = &prect[0];
>
> both work and both give me the same error
> "...differs in levels of indirection from..."


prect2 = (int (*)[100])prect;

Type punning like this is not actually guaranteed to work, but it is
likely to. However, Ben's suggestion has the same effect without
requiring adding a variable to your program.
--
James Kuyper

Ben Bacarisse 02-20-2013 02:01 PM

Re: Struct pointer vs. struct array pointer
 
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> aleksa <aleksazr@gmail.com> writes:
>
>> On Wednesday, February 20, 2013 12:12:18 PM UTC+1, Sebastian Gesemann wrote:
>>> int (*p)[5] = ...;

>>
>> Since my only concern here was how to view entire structure array
>> (or at least some of it) using WinDbg, maybe this is the best:
>>
>> RECT (*prect2)[100];
>>
>> now I can view the first 100 entries, which is more than enough.

>
> If the purpose is simply to view things in a debugger it seems excessive
> to have to alter the source. Can't you use an expression in the
> debugger? I.e. where you now say something like "print prect2" could
> you not say "print *((*)[100])prect"?


I missed the base type out: print *(int (*)[100])prect

<snip>
--
Ben.

Keith Thompson 02-20-2013 04:06 PM

Re: Struct pointer vs. struct array pointer
 
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Wednesday, February 20, 2013 9:17:32 AM UTC, aleksa wrote:
>> Say I'm using a standard windows RECT structure...
>> RECT *prect;
>>
>> prect->left = 0;
>>

> As the code stands, prect is set to whatever random data was in the
> memory space assigned to it. So the second line sets a random memory
> location to zero. Usually the result will be a segmentation fault, but
> not always.
>
> To fix this problem
>
> RECT rect;
> prect = &rect;
>
> but of course this us useless. Why not just write rect.left = 0 instead?
>
>> How can I define a pointer to an array?
>>
>> I don't know in advance how many RECTs there will be in the array.
>>

> It bcoomes useful here
>
> RECT rectarray[15];
>
> rectarray, is to all intents and purposes, a constant pointer to a
> block of 15 RECTs.


No, it bloody well is not. Do you think `sizeof rectarray` yields the
size of a pointer?

rectarray is an *array*. An expression of array type, in most contexts,
is implicitly converted to a pointer to the array object's first
element. The exceptions are when it's the operand of sizeof, _Alignof
(new in C99), unary &, and when it's a string literal in an initializer
used to initialize an array object.

Malcolm and aleksa, you should both read section 6 of the comp.lang.c
FAQ, http://www.c-faq.com/.

> So what if you don't know how many you'll need at compile time?
>
> RECT *rectp = malloc( Nwanted * sizeof(RECT));


Better:

RECT *rectp = malloc(Nwanted * sizeof *rectp);

(and of course you should check that malloc() returned a non-null
pointer).

> for(i=0;i<Nwanted;i++)
> rectp[i].left = 0;
>
> This creates Nwanted RECTs, and sets the left member of them all to zero.
> Nwanted can be an input value.


--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson 02-20-2013 04:12 PM

Re: Struct pointer vs. struct array pointer
 
Sebastian Gesemann <s.gesemann@gmail.com> writes:
> On Feb 20, 10:17*am, aleksa <aleks...@gmail.com> wrote:

[...]
>> How can I define a pointer to an array?

>
> You can still use a variable of type RECT* to point to the first
> element of an array and access the other elements via the subscript
> operator. With respect to its type, it's still just a pointer to a
> single RECT. Depending on who you talk to


No, it doesn't really depend on who you talk to.

> "pointer to an array" could
> mean just that, a pointer that points to the first element of an
> array.


Those people are mistaken.

> To other people "pointer to array" means that the pointee type
> is an array type:
>
> int (*p)[5] = ...;
>
> which reads: p is a pointer to an array of 5 ints.


And those people are correct.

> So, there is some
> potential for confusion there ...


Which is avoided by understanding the difference between a pointer
to an element of an array and a pointer to an entire array.

Pointers to arrays are actually not as useful as you might expect. Most
array manipulation is done via a pointer to an element of the array --
which means you need to keep track of the length of the array
separately.

[...]

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


All times are GMT. The time now is 02:42 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.