|
I think I just ripped through mr.Smith
tried this :
<br />
int py2[2][2] = {10,11,12,13};<br />
<br />
int* sptr = &py2[0][0];<br />
int** dptr = &sptr;<br />
<br />
printf("\nAtlast:%d\n",**dptr);<br />
*dptr+=1;<br />
*dptr+=2;<br />
printf("\nAtlast:%d\n",**dptr);<br />
o/p:10,13
-Anderson. .
|
|
|
|
|
The key point is that arrays and pointers are NOT the same.
An array can be converted into a pointer and pointer arithmetic (and indexing) looks the same as array subscripting, but they aren't. They coincide only for linear indexing (that's the case of monodimensional arrays)
int **pyp2 is a "[pointer to a [pointer to [an int]]]"
The memory layout it expects is like
int** ----> [int*, int*, int*, ...]
| | |
| | |
| | V
| V [int,int,...]
V [int,int,int...]
[int, int, ...]
While int py2[2][2] is an "[array of [array of [int]]]"
The memory layout it expects is like
[[int,int],[int,int]]
That's completely different.
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
As you know pointers & arrays both move consecutive. Then how come it be totally different? To some extent I can agree. Because the next pointer in the **ptr can be made to point to some other *p pointing somewhere. But here that's not the case.. it's array, quite consecutive and we are making our **ptr point to it. What do you think about the below approach ? getting the address of the first row pointer & getting the address of it and then deferencing.
<br />
int py2[2][2] = {10,11,12,13};<br />
<br />
int* sptr = &py2[0][0];<br />
int** dptr = &sptr; <br />
<br />
printf("\nAtlast:%d\n",**dptr); <br />
*dptr+=1;<br />
*dptr+=2;<br />
printf("\nAtlast:%d\n",**dptr);<br />
|
|
|
|
|
It seems you're confusing two well distinct concepts (don't worry: it takes about three years to me to get away from that confusion...).
Let's reconsider your points:
Smith# wrote: As you know pointers & arrays both move consecutive
No. Pointers "move" (in th sense they can receive another address as their own stored value). Array just "are". Array indexes "move" (in the sense they can be used to indicate other array cells).
Smith# wrote: how come it be totally different
Because they ARE totally different. They simple have a "similar" external interface (same operators).If you don't get this point may be I was not able to explain the first point, but until you don't get it you cannot move away from your trivia. So loop over and over until you get it, find other sources than me (if you find my way to explain is not clear) but there is no way to move over until this crucial point is clear.
Smith# wrote: Because the next pointer in the **ptr can be made to point to some other *p pointing somewhere. But here that's not the case.. it's array,
You know, but compiler doesn't.
int** for the compiler is just 4 bytes of memory containing the address of an int* that is another 4 byte of memory, somewhere else, containing the address of an int.
Whatever you think about this is irrelevant to the compiler.
int[] is a consecutive bounce of integers at some place in memory. This place has an address.
When you do
int a[2] = { 0,1 };
int* pa = a;
you assign the address of the array head to the pointer.
When you do
*pa = 5;
the compiler assign 5 to the memory whose address is stored in "pa".
This accidentally is a[0] (but it is not something the compiler is aware of).
When you do
pa[1] = 6;
the compiler assign 6 to the memory whose address is given by pa+1*sizeof(int) , that accidentally is a[1] (again you know, not the compiler: there is nothing in "pa" that makes the compiler aware of the fact that it is NOW pointing to an array and sometime later on to an individual integer and some later on to an integer inside a class or struct.
The design of the [] operator appllied to poitner or to array makes this operation giving a same result just because for monidimensional array, the same calculation is done.
Bidimensional array are different:
int a[2][2] = { 1,2,3,4 };
a[1,1] = 5;
means "set to 5 the cell "1" of the subarray "1" of the bidimensional array.
But
int **ppa = a;
ppa[1][1] = 8;
means: "take the value of "ppa", add 1*sizeof(int*) (note: int* , not int ) fetch the value stored at such address, add 1*sizeof(int) (yes: now it's int ) and this is the address where to store 8 .
Now: since ppa contains the address of a[0][0] and sizeof(int*) is equal to sizeof(int) (at least on 32 bit Win-Intel), ppa[1][1] means:
take the address of a[0][0] add 1*sizeof(int*) (gives incidentally the address of a[1][0]), get the value (it's 2) add 1*sizeif(int) (gives 6) and store 8 to the memory whose address starts at "0x00000006" (6). That's out of your executable address space, hence the crash.
The compiler translate statements one by one without keeping memory of what a statement "means" being after another one.
int[][] is one thing, int** anoter, and the [] operator on a array is different to the [] operator on a pointer. Assigning an array address to a "pointer to pointer" doesn't change its nature of "pointer".
mondimensional array and simple pointer when applied to the [] operator give same results because in this degeneral case, the "resolution formula" is the same, since it start to be different from the second therm, that for one-only indirection, is not present.
2 bugs found.
> recompile ...
65534 bugs found.
modified on Monday, February 9, 2009 2:11 AM
|
|
|
|
|
Hey Sorry man, I'm just checking your reply. Before even reading it I felt I should thank you for your helping effort. I'll read it, and if I find it reasonable, I'll give up the weapons & surrender . Anyway thanks a lot.
|
|
|
|
|
Now, let's move a little bit on:
If you agree with my previous post, consider this:
int a [2][2] = { 1,2,3,4 };
int[2]* ppa = a;
Do you get it? Instead of int**, I use int[2]*: a "pointer to an array of two integers". considering the int[][] as "array of 2 arrays of two integers".
The type of int** is int* (that doesn't exist in memory since we store arrays), but the value of int[2]* is int[2] that's just one row of the matrix ( in our case
{{1,2},{3,4}}
Now ppa[1][1] is "take the address stored in ppa, add 1*sizeof(int[2]). This is the int[2] representing the second row. Now we're anymore dealing with a pointer, but with an array, whose cell "1" has the value "4".
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
I have a non MFC project with couple of .h and .cpp files. Now i wnat to add a class CDbOperations to that project temporarily which will handle the database interatctions. I have used CDatabase, CString, CSemaphore classes in CDbOperations class. I have added required includes as
#include <afxdb.h>
#include <afxmt.h>
int my CDbOperations.h file. When i compile the project i got this error
fatal error C1189: #error : WINDOWS.H already included. MFC apps must not #include <windows.h>
How can i solve this error.
Saadhinchaali
modified on Wednesday, February 4, 2009 2:13 AM
|
|
|
|
|
Tritva wrote: I have a non MFC project with couple of .h and .cpp files.
Tritva wrote: I have used CDatabase, CString, CSemaphore classes in CDbOperations class.
Your app is no longer non MFC app. Classes you mentioned above are from MFC.
Regards,
Sandip.
|
|
|
|
|
Hi Sandip,
SandipG wrote: Your app is no longer non MFC app.
Yes. you are right. But before using that classes, i was developing a non mfc project. Since i needed a dabase interatction i used those classes. Now it has become an mfc project.
Is there a way to getrid of that error?
Saadhinchaali
|
|
|
|
|
Try removing #include <windows.h> from your code.
«_Superman_»
|
|
|
|
|
Hi,
Thank you for the reply.
I have not added the line #include <windows.h> any where in my application.
Saadhinchaali
|
|
|
|
|
add stdafx.h on top of everything in the source file where it points the error.
|
|
|
|
|
Hi Smith,
I dont have a stdafx.h file in my project.
I have created an empty console application and created my .h and .cpp files later.
Saadhinchaali
|
|
|
|
|
Where are you including afxwin.h at?
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
MSDN says the requirements for timeKillEvent are
Windows NT/2000/XP: Included in Windows NT 3.1 and later.
Windows 95/98/Me: Included in Windows 95 and later.
but the requirements for timeSetEvent are
Windows XP: Included in Windows XP only.
Really? Since timeKillEvent uses the return value of timeSetEvent, this doesn't seem to make sense.
|
|
|
|
|
I think that's incorrect - I have a very old copy of the MSDN library (October 2001) that documents timeSetEvent with:
Windows NT/2000/XP: Included in Windows NT 3.1 and later.
Windows 95/98/Me: Included in Windows 95 and later.
Header: Declared in Mmsystem.h; include Windows.h.
Library: Use Winmm.lib.
HTH!
|
|
|
|
|
Hi,
I want to know is there a event/notification/method to know that dialog box is initialized. i.e. OnInitDialog() call is finished, dialog box is visible and all controls on it are visible.
Based on this, I need to show a message box depending upon some condition after dialog box is fully intialized. Right now i am able to do it by Setting a timer in OnInitDialog() function with delay of 400 ms. And then in OnTimer, i am able to show the message box depending upont the condition.
Other methods suggested to me are Use PostMessage() inside the OnInitdialog() with some user defined message and in handler i can show message box. But This does not work as it comes in the handler of User defined message before my dialog box is shown.
Please provide your views on this.
Thanks
Prashant
|
|
|
|
|
May be you can try handling CWnd::OnActivateApp..
Regards,
Sandip.
|
|
|
|
|
Have you tried handling WM_SHOWWINDOW message(OnShowWindow ) ?
You just need to keep track of when you want to use it.
|
|
|
|
|
It's very dull, but what I've done in a similar situation is to have a member variable: m_bInitialised.
CMyDialog () : CDialog (blah)
{
...
m_bInitialised = FALSE;
}
BOOL CMyDialog::OnInitDialog ()
{
...
BOOL bReturn = CDialog::OnInitDialog ();
m_bInitialised = TRUE;
return bReturn;
}
Iain.
Codeproject MVP for C++, I can't believe it's for my lounge posts...
|
|
|
|
|
I have three users viz.
User1
User2
User3
User2 has mapped network drive.
Now when i enumerate drives using GetLogicalDrieStrings in User1, i only get drives of User1.
What i want is to enumerate all the drives including mapped drive in User2 in any user context.
How can i acheive this???
Thanks in advance.
Regards,
K. Sushilkumar.
|
|
|
|
|
Mapped drives are maintained per context.
So a mapped network drive of one user may not be valid for another user.
It is also dependent on the user privileges.
So Z: may be mapped by 2 different users on 2 different locations.
«_Superman_»
|
|
|
|
|
Hi,
I have created client and server application that uses
sockets for communication. But only single client can connect to server.
I have to connect multiple clients to same server.
Can anybody help me?
Thanks in Advance
|
|
|
|
|
You will need a multi-threaded program to handle multiple clients.
One dedicated thread will only wait for new client connections and will not do any other processing.
As soon as a client connects, a new thread is created to handle that particular client.
Either this or you can create the server using IO completion ports.
«_Superman_»
|
|
|
|
|
"you can create the server using IO completion ports".
Can you please explain?
|
|
|
|