Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Struct pointer vs. struct array pointer

Reply
Thread Tools

Struct pointer vs. struct array pointer

 
 
aleksa
Guest
Posts: n/a
 
      02-20-2013
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
 
Reply With Quote
 
 
 
 
Malcolm McLean
Guest
Posts: n/a
 
      02-20-2013
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

 
Reply With Quote
 
 
 
 
Sebastian Gesemann
Guest
Posts: n/a
 
      02-20-2013
On Feb 20, 10:17*am, aleksa <(E-Mail Removed)> 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.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      02-20-2013
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
 
Reply With Quote
 
aleksa
Guest
Posts: n/a
 
      02-20-2013
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..."
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-20-2013
aleksa <(E-Mail Removed)> 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.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      02-20-2013
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
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-20-2013
Ben Bacarisse <(E-Mail Removed)> writes:

> aleksa <(E-Mail Removed)> 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.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      02-20-2013
Malcolm McLean <(E-Mail Removed)> 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) http://www.velocityreviews.com/forums/(E-Mail Removed) <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"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      02-20-2013
Sebastian Gesemann <(E-Mail Removed)> writes:
> On Feb 20, 10:17*am, aleksa <(E-Mail Removed)> 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) (E-Mail Removed) <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"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
(: Pointer to struct withing pointer to struct :) Zero C Programming 16 11-19-2005 01:27 AM
length of an array in a struct in an array of structs in a struct in an array of structs Tuan Bui Perl Misc 14 07-29-2005 02:39 PM
passing pointer->struct->pointer->struct to function. .. ?? beetle C Programming 2 01-25-2005 06:08 PM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM



Advertisments