Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

compiler and pointer addition... 2

Status
Not open for further replies.

fl0ra

MIS
Jul 27, 2004
93
FR
Ok guys,
I've been wasting 30min on that piece of code, ridiculously easy yet it does not gives me the same address....
yet it should...

I just want to understand why...
Here goes the code

void * target=NULL;
void * temporary=NULL;

// that is a pointer to a buffer (some might say array)
// of N struct of type DS_GEP_EPoch

target=datastore.Orbit->Epoch;

// now I wanna move in memory
// from the first struct pointed by
// target to the struct number (v->epoch_number)
// v->epoch_number is an int btw...

target+=(v->epoch_number)*(sizeof(DS_GEP_Epoch));

// Why not doing all that in on line to save some space
// I actually have to do that kind of thing a lot
// of time and therefore won't mind reducing the numbers
// of line a bit...

temporary=datastore.Orbit->Epoch + ((v->epoch_number)*(sizeof(DS_GEP_Epoch)));

// well... let's print up the address


printf("target:\t%d\ntemporary:\t%d\n", target, temporary);
/*
the result of the printf for instance:
target : 1076559741
temporary : 1494148727
*/


// It does not work... the result are different.
// Bear in mind I'm not using any fork or threads
// only on single process.
// I'm pulling my hair off...
 

My guess is that if you change target to be of type DS_GEP_Epoch, then it will work.

I base this on the rules of pointer arithmetic, like adding one to a char ptr adds sizeof(char) to the address; but adding one to a int ptr adds sizeof(int) to the address.

I'm not sure what is added to a ptr of type null.
 
hmmmm...
yeah I tried that as well... but it did not make any diff.
Your guess is, however, correct in other case.
But in that case it still does not explain why
target=datastore.Orbit->Epoch;
target= target + (v->epoch_number)*(sizeof(DS_GEP_Epoch));
temporary=datastore.Orbit->Epoch + ((v->epoch_number)*(sizeof(DS_GEP_Epoch)));

gives differents results...
 
Yes, I tried a simple test with 'target' as a void ptr and it leterally adds one, see first listing. Then I tried it with type casting 'target' to an int and it worked, see listing 2.

Code:
/* listing 1 ---------------------------*/
#include <stdio.h>

void *target=NULL;
int *myint=NULL;

int myarr[100];

main()
{
  myint = myarr;

  printf("myint %d\n", myint);
  myint++;
  printf("myint %d\n", myint);


  target = myarr;

  printf("target %d\n", target);
  [COLOR=red]target++;[/color]
  printf("target %d\n", target);
}
"ptr.c" 24L, 278C written
$ cc -o ptr ptr.c
$ ptr            
myint 134518464
myint 134518468
[COLOR=red]target 134518464
target 134518465[/color]
$ 

/* listing 2 --------------------------*/

#include <stdio.h>
void *target=NULL;
int *myint=NULL;

int myarr[100];

main()
{
  myint = myarr;

  printf("myint %d\n", myint);
  myint++;
  printf("myint %d\n", myint);


  target = myarr;

  printf("target %d\n", target);
  [COLOR=red]target = (int *) target + 1;[/color]
  printf("target %d\n", target);
}

~
"ptr.c" 22L, 295C written
$ cc -o ptr ptr.c
$ ptr            
myint 134518464
myint 134518468
[COLOR=red]target 134518464
target 134518468[/color]
$
 
Add the typecast to target (see boldface below), it will work.

Code:
target=datastore.Orbit->Epoch;
target= [b](DS_GEP_Epoch)[/b]target + (v->epoch_number)*(sizeof(DS_GEP_Epoch));
temporary=datastore.Orbit->Epoch + ((v->epoch_number)*(sizeof(DS_GEP_Epoch)));
 
In the following:
Code:
target= target + (v->epoch_number)*(sizeof(DS_GEP_Epoch));
You add [tt](v->epoch_number)*(sizeof(DS_GEP_Epoch))[/tt] bytes to target because target is a void pointer treated as a char pointer for arithmetic (beware that arithmetic on void pointer is compiler dependant).

In the following:
Code:
temporary = datastore.Orbit->Epoch + ((v->epoch_number)*(sizeof(DS_GEP_Epoch)));
you add [tt](v->epoch_number) * (sizeof(DS_GEP_Epoch))[/tt] to [tt]datastore.Orbit->Epoch[/tt] which (I presume) is a [tt]DS_GEP_Epoch[/tt] pointer. So, using pointer arithmetic, you add [tt](v->epoch_number) * (sizeof(DS_GEP_Epoch)) * (sizeof(DS_GEP_Epoch))[/tt] bytes !
Then you set [tt]temporary[/tt] (a [tt]void[/tt] pointer) to this value.

I think that what you want is just:
Code:
temporary = datastore.Orbit->Epoch + (v->epoch_number);

--------------------

Denis
 
Strictly speaking, you can't use pointer arith on void* pointers at all (see target in the 1st post). A compiler does not know sizeof(void) value - it can't add (or subtract;) an unknown value in that case.
Use char* (or other proper typed) pointers for such low-level buffers...
 
ok guys...
I am gonna make some more test using char * instead.
I'll let you know the outcome asap.
 
I agree with ArkM: pointer arithmetic on void pointer is compiler dependant. Some consider void pointers as char pointers for arithmetic purpose some do not allow it and give a compilation error. To be avoided in portable code.

I think of a cleaner way to express what you want, I mean, get the adress of the first byte of the n'th element of an array (or of a pointer used as an array) and store it in a void pointer. Simply get the adress of this element, like this:
Code:
myVoidPtr = & ( myArray [ n ] );

With your variable names:
Code:
target = &(datastore.Orbit->Epoch[0]);
temporary = &(datastore.Orbit->Epoch[v->epoch_number]);

--------------------

Denis
 
Guys,
and more specifically ArkM et mon amis Denis, I have to say that void * are cr@p.
Denis merci pour tout c'etait super utile...

I switched to char * and everything went smoothly...
I also used denis' idea and that was the trick...

Thx for your help... much appriciate...
 
There's nothing wrong with void*, merely the use to which it was put.


--
 
well yeah...
no arithmetic with void *, this is the lesson I learn.
having say that I will still use void * because it is useful in severals other case.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top