Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Pointer difficulties

Reply
Thread Tools

Pointer difficulties

 
 
spasmous
Guest
Posts: n/a
 
      02-06-2009
Below are two versions of code that I expected to do the same thing.
However they don't. I'm having difficulty seeing what is causing the
different behaviour - can someone please explain it to me! Thank you!!

int n = 10,m=100;
double y[n];
short *p[n]; // pointers to arrays of length m

// this gives the desired result
for(int j=0; j<m; j++) {

for(int k=0; k<n; k++) y[k] = *(p[k]+j);
do_stuff(y);
*(p[0]+j) = (short)y[0];
*(p[1]+j) = (short)y[1];

}

// this does not give the desired result
for(int j=0; j<m; j++) {

for(int k=0; k<n; k++) y[k] = *(p[k]++);
do_stuff(y);
*(p[0]) = (short)y[0];
*(p[1]) = (short)y[1];

}
 
Reply With Quote
 
 
 
 
user923005
Guest
Posts: n/a
 
      02-06-2009
On Feb 5, 11:58*pm, spasmous <(E-Mail Removed)> wrote:
> Below are two versions of code that I expected to do the same thing.
> However they don't. I'm having difficulty seeing what is causing the
> different behaviour - can someone please explain it to me! Thank you!!
>
> int n = 10,m=100;
> double y[n];
> short *p[n]; // An array of ten pointers to short, initialize to NULL
>
> // this gives the desired result
> for(int j=0; j<m; j++) {
>
> * * for(int k=0; k<n; k++) y[k] = *(p[k]+j);
> * * do_stuff(y);
> * * *(p[0]+j) = (short)y[0];
> * * *(p[1]+j) = (short)y[1];
>
> }
>
> // this does not give the desired result
> for(int j=0; j<m; j++) {
>
> * * for(int k=0; k<n; k++) y[k] = *(p[k]++);
> * * do_stuff(y);
> * * *(p[0]) = (short)y[0];
> * * *(p[1]) = (short)y[1];
>
>
>
> }


Neither one is going to do something sensible.

This will compile, but exhibits undefined behavior on first access to
a NULL pointer.

#define n 10
#define m 100
double y[n];
short *p[n]; /* 10 null pointers to short */

void do_stuff(double *y)
{
return;
}

int main(void)
{
int j,k;
/* this supposedly gives the desired result */
for (j = 0; j < m; j++) {
for (k = 0; k < n; k++)
y[k] = *(p[k] + j);
do_stuff(y);
*(p[0] + j) = (short) y[0];
*(p[1] + j) = (short) y[1];
}

/* this does not give the desired result (no surprise there) */
for (j = 0; j < m; j++) {
for (k = 0; k < n; k++)
y[k] = *(p[k]++);
do_stuff(y);
*(p[0]) = (short) y[0];
*(p[1]) = (short) y[1];
}
return 0;
}

I guess that your post is a troll.
 
Reply With Quote
 
 
 
 
spasmous
Guest
Posts: n/a
 
      02-06-2009
On Feb 6, 12:22*am, user923005 <(E-Mail Removed)> wrote:
> On Feb 5, 11:58*pm, spasmous <(E-Mail Removed)> wrote:
>
>
>
> > Below are two versions of code that I expected to do the same thing.
> > However they don't. I'm having difficulty seeing what is causing the
> > different behaviour - can someone please explain it to me! Thank you!!

>
> > int n = 10,m=100;
> > double y[n];
> > short *p[n]; // An array of ten pointers to short, initialize to NULL

>
> > // this gives the desired result
> > for(int j=0; j<m; j++) {

>
> > * * for(int k=0; k<n; k++) y[k] = *(p[k]+j);
> > * * do_stuff(y);
> > * * *(p[0]+j) = (short)y[0];
> > * * *(p[1]+j) = (short)y[1];

>
> > }

>
> > // this does not give the desired result
> > for(int j=0; j<m; j++) {

>
> > * * for(int k=0; k<n; k++) y[k] = *(p[k]++);
> > * * do_stuff(y);
> > * * *(p[0]) = (short)y[0];
> > * * *(p[1]) = (short)y[1];

>
> > }

>
> Neither one is going to do something sensible.
>
> This will compile, but exhibits undefined behavior on first access to
> a NULL pointer.
>
> #define *n *10
> #define *m *100
> double * * * * *y[n];
> short * * * * **p[n]; */* 10 null pointers to short */
>
> void do_stuff(double *y)
> {
> * * * * return;
>
> }
>
> int * * * * * * main(void)
> {
> * * * * int j,k;
> /* this supposedly gives the desired result */
> * * for (j = 0; j < m; j++) {
> * * * * for (k = 0; k < n; k++)
> * * * * * * y[k] = *(p[k] + j);
> * * * * do_stuff(y);
> * * * * *(p[0] + j) = (short) y[0];
> * * * * *(p[1] + j) = (short) y[1];
> * * }
>
> /* this does not give the desired result (no surprise there) */
> * * for (j = 0; j < m; j++) {
> * * * * for (k = 0; k < n; k++)
> * * * * * * y[k] = *(p[k]++);
> * * * * do_stuff(y);
> * * * * *(p[0]) = (short) y[0];
> * * * * *(p[1]) = (short) y[1];
> * * }
> * * return 0;
>
> }
>
> I guess that your post is a troll.


lol hardly. Take a huge leap and imagine p getting initialized without
it being spelt out for you
 
Reply With Quote
 
Martin Ambuhl
Guest
Posts: n/a
 
      02-06-2009
spasmous wrote:
> On Feb 6, 12:22 am, user923005 <(E-Mail Removed)> wrote:

[..]
>> I guess that your post is a troll.

>
> lol hardly. Take a huge leap and imagine p getting initialized without
> it being spelt out for you


Take a huge leap and post real code. When you have problems and leave
out part of the relevant code, the best possible guess is that the part
you left out doesn't exist and that part of your problem lies there.

Unlike Mr. Corbit, I did not take your initial post as a troll. You
snotty and frankly stupid response to him does suggest that he was right.

 
Reply With Quote
 
Ike Naar
Guest
Posts: n/a
 
      02-06-2009
In article <(E-Mail Removed)>,
spasmous <(E-Mail Removed)> wrote:
>Below are two versions of code that I expected to do the same thing.
>However they don't. I'm having difficulty seeing what is causing the
>different behaviour - can someone please explain it to me! Thank you!!
>
>int n = 10,m=100;
>double y[n];
>short *p[n]; // pointers to arrays of length m
>
>// this gives the desired result
>for(int j=0; j<m; j++) {
> for(int k=0; k<n; k++) y[k] = *(p[k]+j);
> do_stuff(y);
> *(p[0]+j) = (short)y[0];
> *(p[1]+j) = (short)y[1];
>}
>
>// this does not give the desired result
>for(int j=0; j<m; j++) {
> for(int k=0; k<n; k++) y[k] = *(p[k]++);
> do_stuff(y);
> *(p[0]) = (short)y[0];
> *(p[1]) = (short)y[1];
>}


In the second variant, you increment p[k], for every k in 0..n-1,
at the start of the body; that means that at the end of the body
p[0] and p[1] alreay have been incremented, so the assignment

*(p[0]) = (short)y[0];

does not do the same thing as the corresponding assignment in the
first variant. Look what happens if you change the assigment to:

*(p[0]-1) = (short)y[0];

Regards,
Ike
 
Reply With Quote
 
spasmous
Guest
Posts: n/a
 
      02-06-2009
On Feb 6, 1:41*am, Martin Ambuhl <(E-Mail Removed)> wrote:
> spasmouswrote:
> > On Feb 6, 12:22 am, user923005 <(E-Mail Removed)> wrote:

> [..]
> >> I guess that your post is a troll.

>
> > lol hardly. Take a huge leap and imagine p getting initialized without
> > it being spelt out for you

>
> Take a huge leap and post real code. *When you have problems and leave
> out part of the relevant code, the best possible guess is that the part
> you left out doesn't exist and that part of your problem lies there.
>
> Unlike Mr. Corbit, I did not take your initial post as a troll. *You
> snotty and frankly stupid response to him does suggest that he was right.


lol this is hilarious, real passion!! anyway, thanks I won't need your
"best possible guess" this time (which was also wrong). he he, arguin
on the internets...
 
Reply With Quote
 
spasmous
Guest
Posts: n/a
 
      02-06-2009
On Feb 6, 4:48*am, Han from China <(E-Mail Removed)>
wrote:
> spasmouswrote:
> > Below are two versions of code that I expected to do the same thing.
> > However they don't. I'm having difficulty seeing what is causing the
> > different behaviour - can someone please explain it to me! Thank you!!

>
> > int n = 10,m=100;
> > double y[n];
> > short *p[n]; // pointers to arrays of length m

>
> > // this gives the desired result
> > for(int j=0; j<m; j++) {

>
> > * *for(int k=0; k<n; k++) y[k] = *(p[k]+j);

>
> Each iteration of the top loop results in populating y[] with the j'th column
> of a 10x100 matrix.
>
> > * *do_stuff(y);
> > * **(p[0]+j) = (short)y[0];
> > * **(p[1]+j) = (short)y[1];

>
> Elements 0,j and 1,j of the 10x100 matrix are altered. This doesn't affect
> the next iteration, since the j'th column has already been used.
>
> > }

>
> > // this does not give the desired result
> > for(int j=0; j<m; j++) {

>
> > * *for(int k=0; k<n; k++) y[k] = *(p[k]++);

>
> Each iteration of the top loop results in populating y[] with the j'th column
> of a 10x100 matrix. Same as in the first version.
>
> > * *do_stuff(y);
> > * **(p[0]) = (short)y[0];
> > * **(p[1]) = (short)y[1];

>
> Elements 0,(j+1) and 1,(j+1) of the 10x100 matrix are altered. This affects
> the next iteration, since the (j+1)'th column has not already been used.
> The program has undefined behavior because the final iteration results in
> two stores to an "element" one past the final element of an array. Note that the
> *(p[k]++); which gets there is fine, since you're allowed to store the
> address of the "element" one past the final element of an array, but you're
> not allowed to access the "element" there for either a read or a write, and
> you write there with the final stores to *(p[0]) and *(p[1]).
>
> > }

>
> I have modified your code to use a 2x5 matrix, to make do_stuff() a no-op,
> and to print some debugging output. I have used a virtual 6th column
> initialized with the value of 42 to show the overwrite in the final
> iteration of your second code version.
>
> #include <stdio.h>
>
> int n = 2, m = 5;
> double y[2];
> short array1[] = {1, 2, 3, 4, 5, 42};
> short array2[] = {6, 7, 8, 9, 0, 42};
> short *p[2] = {array1, array2}; // pointers to arrays of length m
>
> void showit(void)
> {
> * *printf("%f %f\n", y[0], y[1]);
>
> * *printf("%d %d %d %d %d %d\n",
> * * * * *array1[0], array1[1], array1[2], array1[3], array1[4], array1[5]);
>
> * *printf("%d %d %d %d %d %d\n",
> * * * * *array2[0], array2[1], array2[2], array2[3], array2[4], array2[5]);
>
> }
>
> int main(void)
> {
> int j, k;
> #ifdef VERS1
> // this gives the desired result
> for(j=0; j<m; j++) {
>
> * * for(k=0; k<n; k++) y[k] = *(p[k]+j), showit();
> * * //do_stuff(y);
> * * *(p[0]+j) = (short)y[0], showit();
> * * *(p[1]+j) = (short)y[1], showit();
>
> }
>
> #else
> // this does not give the desired result
> for(j=0; j<m; j++) {
>
> * * for(k=0; k<n; k++) y[k] = *(p[k]++), showit();
> * * //do_stuff(y);
> * * *(p[0]) = (short)y[0], showit();
> * * *(p[1]) = (short)y[1], showit();}
>
> #endif
>
> * return 0;
>
> }



Han and Ike, thank you so much. Of course it's obvious now

 
Reply With Quote
 
John Bode
Guest
Posts: n/a
 
      02-06-2009
On Feb 6, 1:58*am, spasmous <(E-Mail Removed)> wrote:
> Below are two versions of code that I expected to do the same thing.
> However they don't. I'm having difficulty seeing what is causing the
> different behaviour - can someone please explain it to me! Thank you!!
>
> int n = 10,m=100;
> double y[n];
> short *p[n]; // pointers to arrays of length m
>


I'm assuming the elements in p are assigned before the following code
executes, otherwise bad things happen. Basically, p is treated as a
10x100 array of short, right?

> // this gives the desired result
> for(int j=0; j<m; j++) {
>
> * * for(int k=0; k<n; k++) y[k] = *(p[k]+j);


You can use a subscript operator on a pointer if you're treating the
pointer as an array; IOW, you could write p[k][j] as opposed to *(p[k]
+j). That might clarify things.

Are you assigning shorts to doubles by design?

> * * do_stuff(y);
> * * *(p[0]+j) = (short)y[0];
> * * *(p[1]+j) = (short)y[1];


Basically, you're doing

p[0][0] = y[0]; // j = 0
p[1][0] = y[1];
p[0][1] = y[0]; // j = 1
p[1][1] = y[1];
p[0][2] = y[0]; // j = 2
p[1][2] = y[1];
...

etc. Is that the intent?

>
> }
>
> // this does not give the desired result
> for(int j=0; j<m; j++) {
>
> * * for(int k=0; k<n; k++) y[k] = *(p[k]++);
> * * do_stuff(y);
> * * *(p[0]) = (short)y[0];
> * * *(p[1]) = (short)y[1];
>


That expands to

p[0][0] = y[0];
p[1][0] = y[1];
p[0][0] = y[0];
p[1][0] = y[1];
...

etc.
>
>
> }- Hide quoted text -
>
> - Show quoted text -


What exactly *is* the desired result?
 
Reply With Quote
 
Default User
Guest
Posts: n/a
 
      02-06-2009
spasmous wrote:

> he he, arguin on the internets...


Historically, that has been one of its prime functions.




Brian

--
Day 3 of the "no grouchy usenet posts" project
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      02-07-2009
spasmous wrote:
>
> Below are two versions of code that I expected to do the same
> thing. However they don't. I'm having difficulty seeing what is
> causing the different behaviour - can someone please explain it
> to me! Thank you!!
>
> int n = 10,m=100;
> double y[n];
> short *p[n]; // pointers to arrays of length m
>
> // this gives the desired result
> for(int j=0; j<m; j++) {
> for(int k=0; k<n; k++) y[k] = *(p[k]+j);
> do_stuff(y); ^-- ** This is 0 thru 99
> *(p[0]+j) = (short)y[0];
> *(p[1]+j) = (short)y[1];
> }
>
> // this does not give the desired result
> for(int j=0; j<m; j++) {
> for(int k=0; k<n; k++) y[k] = *(p[k]++);
> do_stuff(y); ^-- ** This incr is 1
> *(p[0]) = (short)y[0];
> *(p[1]) = (short)y[1];
> }


See the '**' annotations above.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
 
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
Pointer to pointer or reference to pointer A C++ 7 07-05-2011 07:49 PM
Pointer to pointer Vs References to Pointer bansalvikrant@gmail.com C++ 4 07-02-2009 10:20 AM
passing the address of a pointer to a func that doesnt recieve a pointer-to-a-pointer jimjim C Programming 16 03-27-2006 11:03 PM
Pointer-to-pointer-to-pointer question masood.iqbal@lycos.com C Programming 10 02-04-2005 02:57 AM
Shared pointer difficulties Dave C++ 0 01-11-2005 10:01 PM



Advertisments