|
Folks,
Quick question in relation to the Pointer Maths in this program below, The Output is as follows:
1, 2, 3
. . .
. . .
. . .
245026, 245027, 245028
246017, 246018, 246019
247010, 247011, 247012
248005, 248006, 248007
249002, 249003, 249004
The Last Record is : 245028
Using the MoveBack function I expected the output to be 248007, the record before the current record, however it seems we move back 12 blocks of memory to 245028 and not the 12bytes I expected. Can someone explain to me whats going on here and how I can modify the code to get 248007 from the function? Thanks In Advance
#include "stdafx.h"
#include <conio.h>
typedef struct MyStruct{
int i;
int j;
int k;
} TheStruct;
int MoveBack(int *iPos);
int main(int argc, char* argv[])
{
TheStruct ts[500];
int i = 0;
for(i = 0; i < 500; i++)
{
ts[i].i = i * i + 1;
ts[i].j = i * i + 2;
ts[i].k = i * i + 3;
}
for(i = 0; i < 500; i++)
{
printf("%ld, %ld, %ld \r\n" ,ts[i].i ,ts[i].j, ts[i].k);
if(i == 499)
{
printf("The Last Record is : %ld" , MoveBack(&ts[i].k));
}
}
while(!getch());
return 0;
}
int MoveBack(int *iPos)
{
int *i = iPos - sizeof(TheStruct);
return *i;
}
|
|
|
|
|
Adding or subtracting from a pointer will always be done in multiples of the size of the type pointed to. In this case, MoveBack subtracts 12 times the size of an int from the address, since i points to an int (or at least that's how you declared it). If you don't want that, you have to use void* rather than int* .
That said, it's a horrible idea to cast a pointer into an array of some struct to int* ! Why don't you just pass a pointer to MyStruct instead? Also, it's an even worse idea to dereference an int pointer that in truth points to a struct. This may or may not work, depending on the compiler. And if you ever choose to modify your struct later, the code will likely break (provided it did actually work before).
MyStruct* MoveBack(const MyStruct* p)
{
return p-1;
}
printf("The Last Record is : %ld" , MoveBack(&ts[i])->k);
P.S.: Note that this solution
a) makes the function independent of the definition of MyStruct
b) gets rid of error prone type casts
c) removes the need to use sizeof
d) is actually shorter, to the point that you could inline it, or simply forgo the function alltogether (e. g., above you could write (&ts[i]-1)->k )
P.P.S.: you could of course just use ts[i-1].k
That would be technically equivalent to the code I suggested under d) above
modified on Tuesday, July 12, 2011 9:59 AM
|
|
|
|
|
What if p points to element 0 of the array? How would you check for this?
|
|
|
|
|
You can't. Not inside MoveBack() anyway. Which is yet another good argument not to meddle with pointers recklessly.
The only way to ensure a pointer is inside the scope of an array is to compare it to the start address, and only the function that defined the array knows it.
So if you really wanted a 'safe' MoveBack function, you'd have to add a parameter, like this:
MyStruct* MoveBack_s(const MyStruct* p, const MyStruct* parray)
{
MyStruct* result = 0;
if (p > parray)
result = p-1;
return result;
}
Of course, even this function is not safe if you pass it a pointer to the start of a different array...
The only way to be truly safe is not to use pointers, but iterators, such as those used for the STL class vector. They contain references to the container they refer to and therefore can check their boundaries themselves.
|
|
|
|
|
When using sizeof with a structure it is not guaranteed that you get the sum of the single components due to Structure padding (wiki for it). Just printf the sizeof() of your struct and you will see that its not 12 Bytes.
Anyway it is very unclear to me why are you even trying to do it this way. Dont mess with addresses and pointers in such an unsafe way. Who even tells you that you could just decrease the given int pointer and it would still point to a valid adress.
E.g. just use the indices of the array to get the last element.
|
|
|
|
|
I made a code snippet to print the size of his structure and it was in fact 12 bytes.
|
|
|
|
|
Well i was a bit fast with saying that it will not be 12 bytes. Of course it depends on the compiler. I just wanted to state that its not allways 12 bytes.
|
|
|
|
|
Why on earth was this rated as a bad answer?
Each of the points made are valid and important. Let's see if a 5 won't help!
|
|
|
|
|
Legor wrote: When using sizeof with a structure it is not guaranteed that you get the sum of the single components due to Structure padding
But it doesn't matter since you will always get the size of the actual structure as created by the compiler, so you can still use sizeof to increment a void pointer.
However, as you rightly point out, that is a stupid way to do it since normal increment/decrement or indexing is the correct way.
The best things in life are not things.
|
|
|
|
|
Hi all,
i have an list that contains some items say N items.
i have assigned x number of process to do processing over N List Items.
for example if (x=2) number of process work on processing of (N=20) List Items, so its start from starting two List items when any process finished first than move on 3 one and so on until last item of List.
so please help me how can i do this.
thanks in advance.
|
|
|
|
|
Cannot you use just threads instead of processes?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
when i use thread its end after execution of one list item? how can i set it like this first only assigned number of threads running and execute function on the bases of list item data, after execution check if list have any other item to be execute than execute this.
|
|
|
|
|
If I got you (the requirements aren't very clear), yes. However you should learn a bit how threads (or processes if you like) work. Have a look at: "About Processes and Threads"
[^] at MSDN.
Another worthy reading is the Newcomer's: "Thread and Processes series"[^] series.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
modified on Wednesday, July 13, 2011 3:22 AM
|
|
|
|
|
|
Sorry. Fixed now.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Well, you can have multiple processes work together by communicating between them using pipes or sockets, but like it was already suggested, threads would probably be the most applicable solution to this. If the processes are doing the same thing, there's a perfect example of using CWinThread derived threads, by deriving (or subclassing), its easy to make multiple instances of the desired thread.
|
|
|
|
|
If you do in fact mean 'process' then the first step in the solution is explaining exactly what form the 'list' takes.
|
|
|
|
|
list taking some information that is communicate using ports,
i am having 2 and more port number for communication.
one port can use details from list and communicate after finish it use another item to do this ,coz if i want to access the port that is already in use it gives an error of access denied.
so please help me how can i do this?
thanks in advance.
|
|
|
|
|
Beej's Guide to Network Programming
Not so much for threads and processes but for a great read on ports. If I have understood your need correctly, this reference should help you.
|
|
|
|
|
The "List Hold'n'Synchron Kernel" could lie in a singleton COM EXE-server,
while some its clients could:
- ask for a value associated with a cockie-ID from the server
- precess on that value
- send the modified value associated with the cockie-ID to the server
You could also play
with the different appartment models of the server...
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
|
|
|
|
|
can anybody please provide me any sample or example code.
|
|
|
|
|
Hi Developers,
I want to set the multi selection property of a list box as TRUE through the code, in OnInitDialog(). I can do it from the resource view( dialog box ), but that dialog has used in so many modules.
Thanks.
Amrit Agrawal
|
|
|
|
|
See the notes here[^], this property cannot be turned on programmatically.
The best things in life are not things.
|
|
|
|
|
Just replace your resource list box by a static box (IDC_STATIC_LIST, "VISIBLE" = false),
then create a member list box in the OnInitDialog() function
by usage of the client position of the IDC_STATIC_LIST, current resource styles,
and the (passed in dialog constructor) multiselection flag
(Do not destroy any child explicitly)
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
|
|
|
|
|
Hi developers,
I want to handle TVM_DELETE or TVN_DELTEITEM from a custom tree control in other file( which is derived from CFormView ). From tree control, I am trying to send
<pre> SendMessage(TVM_DELETEITEM, WPARAM(0), LPARAM(hItem));
I have handled this msg in view file like this
<pre> ON_MESSAGE(TVM_DELETEITEM, OnTvmDeleteItem )
but it simply delete the item and doesn't caught at OnTvmDeleteItem().
I have also tried to send TVN_DELTEITEM with ON_NOTIFY_MESSAGE(), but still it doesn't work.
Pls help me out.
Thanks.
|
|
|
|