|
Thank you Viorel!
Your reply is excellent!! I think both data segment and heap are used to provide global access through a process (that is, compared with stack, variable will disappear when function returns, but in data segment or in heap, variable will be valid and accessible through the life-cycle of a process). My question is that, why system needs to divide global data access through a process into data segment and heap -- they are both used for the same purpose (global data access through a process), what are the different functions between them?
regards,
George
|
|
|
|
|
Data segment is a storage for named variables, declared like "int x = 0; " or "static int x = 0; " outside functions, or as "static int x = 0; " inside functions. Data segment also stores initial value of arrays, like "Hello, World!" for strings, or {1, 2, 3} for integer arrays. This data segment is allocated once, when process starts, and the number of variables here cannot grow.
(One more thing which is stored in data segment is "virtual tables" of classes having virtual functions).
Heap area is for unnamed variables, allocated only when you explicitly call new or related. So the number of variables varies here during program execution.
While variables declared in global data segment can be accessed by name, the variables allocated in heap have to be accessed by pointers or references.
So the main difference between global data segment and heap is that the size of data segment is fixed, while the data allocated in the heap can vary.
That is my understanding.
|
|
|
|
|
Thank you Viorel!
I agree with all of your great points. Except that, you think we do not access the variable on heap by its name. I think all types of variables are accessed by name.
For example,
int* pi = new int [5];
variable pi is allocated on heap, but later when we want to access this variable, we also use the variable name "pi", right? Why you say we do not access variable by its name if the variables are on heap?
> "Heap area is for unnamed variables"
regards,
George
|
|
|
|
|
In declarations like
int * pi = new int[5];
you actually have two variables. First is pi , which is a pointer. It is allocated on the stack (in case of functions) or in data segment (if is outside of functions). The size of pi is usually four bytes. Another variable is the array allocated by new in heap area. This variable has no name, by has an address (for instance 0x1234 ), returned by new , which is assigned to the pi variable. The size of this array is twenty bytes.
Therefore the content of the pi variable is the address of the array, but not the content of array. When you use pi , you actually denote the address -- 0x1234 . For instance, when you call a function, f(pi) , you pass the 0x1234 value to the function, but not the content of array.
When you use delete pi , the unnamed array is deleted, but the pi variable is still available for another assignments.
In order to work with the referenced values via pointer, you use expressions like pi[3] or *(pi+3) .
Actually, in case of data allocated on the heap, you can simulate an assignment of a name, using references. For instance:
int * z = new int;
int & r = *z;
In this case, r is a synonym for the integer allocated on the heap, and the usage of r will be treated as an access to this integer. For instance, r = 200 will assign a new value to that integer. Here, z still denotes an address, but r denotes the value on the heap. So, now that integer has a name -- r ;
Internally, references are stored as pointers, i.e. they contain addresses of referenced variables. They are a convenient way for working with addresses, because "r " is simpler than "*z ".
Therefore we can say that references offer a way for assigning names to variables allocated on the heap.
That is the picture in my opinion.
|
|
|
|
|
Thank you Viorel!
You have answered all of my questions!
regards,
George
|
|
|
|
|
I know this isn't really a C++ question, but Quaternions are commonly used by many C++ coders so I'll ask this here...
I am trying to rotate object A by the reverse of object B's orientation, where I know the orientations of each in quaternion form.
I can do this by converting the quaternion B to a matrix and multiplying A by the inverse of Matrix B, but this seems like a waste or processing power.
What other methods can I use to reverse the rotation of a Quaternion? Would negative scaling work?
When I die I'd like to go peacefully in my sleep like my father, not screaming in terror like his passengers!!!
|
|
|
|
|
Im developing a C++ software on winXP that send and receive SMS using serial port GSM modem..
my stucture now is using two threads ..
1.The first one to write to port and other operations(buttons,funs,..)
2.The second one is to read from port ,it blocks untill there is some thing to be read.
now I want my program to show a message whenever there is a new SMS(the modem notify when there is new SMS automaticilly)
should I make another thread to check the buffer after its read from the reading thread?
or should i implement the check inside the reading thread?
remember that checking for new SMS would be blocking the thread its in sinse its implemented in while loop and/or WaitForSingleObject (using events)
any suggestions?
thanks...
|
|
|
|
|
I see two options.
1. Have the receiving thread post a message to your UI thread to process the received SMS message data and display your information.
2. Separate the UI thread from the serial reading thread AND make another thread for writing. Then you have a UI thread and two worker threads. Either worker thread can notify the UI thread, which would rarely be blocked on any communications issue, of actions to take, such as processing the received SMS message.
What I typically did in COM applications was to have two thread-safe buffers, one for reading and one for writing. My UI thread would post data into the
'output' buffer and signal the serial output (writing) thread data was ready for writing. The serial input (reading) thread would post data to an 'input' buffer, and then signal the UI thread that input data was ready to be processed. Worked really well and kept the UI responsive.
I've seen better runs in my shorts! - Patches O'Houlihan
|
|
|
|
|
Does event socket model have to wait for events in another thread in an interactive app?
|
|
|
|
|
if ur lengthy question can put in a subject, then no need of Body for a thread.
Codeproject Admins pls remove this option.
Make clear ur question with apropriate subject and question.
SaRath.
"Don't Do Different things... Do Things Differently..."
|
|
|
|
|
|
Hi, there,
I added a spin button in my dialog and its name is IDC_SPIN_TAP. Its property is
UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS
I added a class variable CSpinButtonCtrl m_wndSpinTap in the header file. In the cpp file,
<br />
DDX_Text(pDX, IDC_EDIT_TAP, m_nTapNum);<br />
DDV_MinMaxInt(pDX,m_nTapNum,0,100000);<br />
DDX_Control(pDX, IDC_SPIN_TAP, m_wndSpinTap);<br />
......<br />
m_wndSpinTap.SetRange(0,100000);<br />
where IDC_EDIT_TAP is its buddy control. When I clicked the up-arrow of the spin button, the number in the buddy edit window was supposed to increase by one like 0,1, 2, 3.... But strangely, the number becomes 0, -1, -2, -3.... When I clicked the down-arrow of it, the number changed from -3, -2, -1, and stops at zero. How could this happen? Did I miss any setting for the spin button?
Thank you very much!
David
|
|
|
|
|
SetRange() has a maximum range of 32676, use SetRange32() instead.
You may be right
I may be crazy
-- Billy Joel --
Within you lies the power for good - Use it!
|
|
|
|
|
Yeah, solved. thank you very much!
David
|
|
|
|
|
I have a grid that is populated by a recordset that contains the result of a query. When I have a large database (about 80,000 records and above..) it takes a few minutes to load the grid with all of the records. And I need to make this faster...
What I thought to do is load the data page by page, and display 400 records in each page. So, it would work this way: display 400 records, then display another 400 (800 total), and so on until I reach 78000 records.
But I don't know how to actually implement this...
Do I have to fill the recordset first with 400 records, then with 800 records, then with 1200 records, etc and eventually with 78000? Or maybe I can use a number of recordsets - and if so how do I do this?
|
|
|
|
|
Hi guys,
I am using DirectX functions ( Back Surface - primary surface concept & Blt functions ) for clip image ( 300 image frames, which are continuoulsy displayed one after other ) display in a dialog based application. The problem is that, when the movie frames are displayed in a machine having Martox G400 series card, it is getting better performance, but when the same application is run in a machine having NVIDIA Mx/M2 400 series card, the performance is very low. Please help me, whether any directx related changes has to be made in the source code or how to solve this problem ?
Velayudhan
|
|
|
|
|
|
Hello everyone,
I need to represent long integer (longer than 8 bytes, which can not be represented by C/C++ built-in types). I need to implement add (+) and multiply (*) operations on such data structures efficiently. Does anyone have ideas of how to implement it or any reference materials?
thanks in advance,
George
|
|
|
|
|
George_George wrote: longer than 8 bytes, which can not be represented by C/C++ built-in types
Please have a look at THIS[^]. (I haven't really read it yet, but found it just now.)
Maxwell Chen
|
|
|
|
|
Thank you Maxwell!
It is a very good reference material!
regards,
George
|
|
|
|
|
|
Hi Maxwell,
This class is also very useful. You have so many good materials.
regards,
George
|
|
|
|
|
I am looking for Win32 support.
and i am trying to use GetOpenFileName.
The my code snippet is:
OPENFILENAME ofn;
char szFile[260];
HWND hwnd;
HANDLE hf;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = (LPWSTR)szFile;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = (LPCWSTR)"All\0*.*\0Text\0*.TXT\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
DWORD err;
if (GetSaveFileName (&ofn)==TRUE)
{
hf = CreateFile(ofn.lpstrFile, GENERIC_READ,0,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,(HANDLE) NULL);
}
else
err = CommDlgExtendedError();
But i am returned with err = 0xFFFF .i.e.
CDERR_DIALOGFAILURE: The dialog box could not be created. The common dialog box function's call to the DialogBox function failed. For example, this error occurs if the common dialog box call specifies an invalid window handle.
Please help.
|
|
|
|
|
try this
<br />
static char File [260];<br />
OPENFILENAME m_ofn;<br />
memset(&m_ofn, 0, sizeof(m_ofn));<br />
m_ofn.lStructSize = sizeof(OPENFILENAME);<br />
m_ofn.hwndOwner = m_hWnd;<br />
m_ofn.hInstance = AfxGetApp()->m_hInstance;<br />
m_ofn.lpstrFilter = "All files(*.*)\0*.*\0";<br />
m_ofn.lpstrCustomFilter = NULL;<br />
m_ofn.nMaxCustFilter = 0;<br />
m_ofn.nFilterIndex = 0;<br />
m_ofn.lpstrFile = File ;<br />
<br />
m_ofn.nMaxFile = sizeof(File );<br />
m_ofn.lpstrFileTitle = 0;<br />
m_ofn.nMaxFileTitle = 0;<br />
m_ofn.lpstrInitialDir = NULL;<br />
<br />
m_ofn.lpstrTitle = "Save a File";<br />
m_ofn.nFileOffset = 0;<br />
m_ofn.nFileExtension = 0;<br />
m_ofn.lpstrDefExt = NULL;<br />
m_ofn.lCustData = 0;<br />
m_ofn.lpfnHook = NULL;<br />
m_ofn.lpTemplateName = NULL;<br />
<br />
m_ofn.Flags= OFN_HIDEREADONLY|OFN_EXPLORER |OFN_ENABLEHOOK ;<br />
<br />
GetSaveFileName(&m_ofn);<br />
<br />
whitesky
|
|
|
|
|
thanks whitesky....
it does work, with minor changes....
m_ofn.hInstance = AfxGetApp()->m_hInstance;
is not working
m_ofn.lpstrTitle = (LPCWSTR)L"Save a File";
m_ofn.lpstrFile = (LPWSTR)File ;
|
|
|
|
|