|
jonsey29847 wrote: I really need a a good Win32 book (Peitzold?)
I learned Windows 3.? from Petzold book. It certainly covered the fundamental topics. I have not read his Win32 book, when I started Win32 development I just used the SDK books.
jonsey29847 wrote: the confusion I seem to have here is allocating memory for a struct.
That's not really a specific topic. Depending on the definition of the struct the allocation issues can be quite different.
IMHO here is a short list of C/C++ issues that one needs a firm grasp of before continuing with the language.
* Heap vs Stack memory
* Memory Addressing / Pointers / Arrays
* Memory allocation and freeing
* Initialization of memory and ramifications of not initializing memory.
* Function execution, i.e., pushing the parameters onto the stack and then jumping and how they return
led mike
|
|
|
|
|
led mike wrote: That's not really a specific topic. Depending on the definition of the struct the allocation issues can be quite different.
Can you cite some examples, my struct is simple 3 pointers to TCHARs and 2 ints.
led mike wrote: * Heap vs Stack memory
* Memory Addressing / Pointers / Arrays
* Memory allocation and freeing
* Initialization of memory and ramifications of not initializing memory.
* Function execution, i.e., pushing the parameters onto the stack and then jumping and how they return
My score is about 3 for 5 here, I think I am getting a lesson on Heap/Stack and Allocation and freeing.
Tom
|
|
|
|
|
jonsey29847 wrote: my struct is simple 3 pointers to TCHARs
That is a perfect example of "not simple".
TCHAR * is an address in memory to a block of TCHAR where the length of the block is undefined in your structure, which Mark Salsbery has pointed out.
Therefore when you allocate the memory for the struct on the stack only the 4 byte address member is allocated, not the space you need to hold the string you want that to point to.
Even if you calculate the space required and allocate on the heap you still don't have the memory structure you think you do in the struct and you would have to use math to address the starting points in memory to all the space you allocated for those strings. That is not advisable or Best Practice by the way.
jonsey29847 wrote: My score is about 3 for 5 here
It's possible you may not have accurately assessed your situation.
led mike
|
|
|
|
|
led mike wrote: It's possible you may not have accurately assessed your situation.
It would not be the first time, nor I expect the last.
It seems the deeper I get into this the greater the complexity.
Ah, well...
Tom
|
|
|
|
|
led mike,
This is what I have taken away from all this;
1. An array does not have to reside in contigous memory, thus I was not corrupting the code, I found something interesting that was causing the apparent (debug only) problem, and a bug in my code.
2. As each element of an array is initialized the operating system will take care of pointer offsets. Duh?
3. In the function that reads the file and populates the array I am using LocalAlloc(LPTR, MaxSize) to initialize intermeadiate variables to hold the data as it is read. I am reinitializing theses variables by using the strcpy function to copy an empty string into the variable. My thinking is that the best practice would be to use ZeroMemory to to reinitialize, this should cover the possiblity of random data causing some kind of problem.
Last night I purchased Petzolds book from Amazon, and I have online access to it neat eh, I have already learned a few neat tricks that I can't wait to use.
Thanks for your help.
|
|
|
|
|
Modified: My answer doesn't allow for expansion.
Doing some sums...
0x4000 = 16384.
x 40 (5 things, at 8 byte spacing) = 655360 = 0.6Mb.
Allocating it as you did, puts the array on the stack - which can only cope with a small (in the grand scheme) amount of memory.
Possible your stack is getting corrupted.
1/ Make sure your memory access is only using the allocated memory.
2/ Try allocating the memory on the heap:
DTC *DTCodes = new DTCodes [0x4000];
...
DTCodes [97].nIndex = 77;
...
delete [] DTCodes;
Good luck,
Iain.
Iain Clarke appearing in spite of being begged not to by CPallini.
|
|
|
|
|
Hey Iain what machine/compiler have you?
sizeof(DTC) gives 20 on my system.
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
|
|
|
|
|
I was pulling numbers out of mid-air. And I wasn't sure if packing would be a problem. 8byte packing, x 5 thingies = 40.
It also made the numbers bigger to illustrate the issue.
If people assume I do vast research to answer their questions, they're baaaaadly mistaken.
(OK, occasionally they're right - the whole shortcut path name in a shell extension question a few days ago tickled my curiosity and stubbornness)
Iain.
Iain Clarke appearing in spite of being begged not to by CPallini.
|
|
|
|
|
Thanks, your answer is just what I was looking for, I will try new.
|
|
|
|
|
The sizes of the members are:
struct DTC{
TCHAR *Code; 6 Bytes
TCHAR *Description; 256 Bytes
TCHAR *Defined; 256 Bytes
int nDefined; 4 Bytes
int nIndex; 4 Bytes
};
526 * 4000 = 2.1M WOW! Is my math correct?
|
|
|
|
|
jonsey29847 wrote: Is my math correct?
Math, yes...structure size, no...
With 32-bit pointers:
struct DTC{
TCHAR *Code; 4 Bytes
TCHAR *Description; 4 Bytes
TCHAR *Defined; 4 Bytes
int nDefined; 4 Bytes
int nIndex; 4 Bytes
};
20 * 4000 = 80000 not so WOW
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
My turn to be picky!
It was 0x4000, so a biiiiit bigger, but even so.
Iain.
Iain Clarke appearing in spite of being begged not to by CPallini.
|
|
|
|
|
Not in the post I replied to
jonsey29847 wrote: 526 * 4000 = 2.1M WOW! Is my math correct?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: Not in the post I replied to
OK, I'll let you off, by reason of you being correct.
Curse you, Gaaaaadgetttt!
Iain.
Iain Clarke appearing in spite of being begged not to by CPallini.
|
|
|
|
|
|
But ultimately won't I need the 2M, and if so when I load the records could I be corrupting code or the stack?
Where is the data read from the file located?
|
|
|
|
|
You'll be allocating 0x4000 structs or 4000?
Assuming 32-bit , non-Unicode (TCHARs are chars) build ...
truct DTC{
TCHAR *Code; pointer to 6 bytes
TCHAR *Description; pointer to 256 Bytes
TCHAR *Defined; pointer to 256 Bytes
int nDefined; 4 Bytes
int nIndex; 4 Bytes
};
20 bytes for each struct
518 bytes allocated for the strings in each struct
Add those together and multiply by the number of structs....that's approximately how
much memory total you'll be allocating (not all in one chunk though). (Depending on
how the string allocations are made, there may be some overhead in each allocation
so the total will actually be more)
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
jonsey29847 wrote: Is my math correct?
Nope!
sizeof(TCHAR *) will be 4 on a 32 bit system - it's just a pointer. The size of the chunk of ram it points to is a separate issue.
It's like saying a postcard is reeeeally heavy, because you've written the address of your friend's house on it.
CPallini already did the sums for me, and he says the size is 20 - so each of the five variables takes 4 bytes. (And he'll pick on me for using 40 again...)
On another point... If you're making a structure containing pointers, then it's good to have a constructor to initialise them to NULL, and a destructor to delete the strings too (if not NULL!).
If the TCHAR *'s point to a fixed string length, then you may want to just put that inline in the struct.
eg:
struct DTC {
TCHAR Code [6];
...
};
etc.
You may have noticed I used delete [] to tidy up - that will call the destructor on each struct in the array if it exists.
Yet another thing - the sizeof the string pointed to by the TCHAR * may depend on whether you have unicode enabled or not. TCHAR = 2 bytes in unicode.
Iain.
Iain Clarke appearing in spite of being begged not to by CPallini.
|
|
|
|
|
Iain,
I am a little confused on how this is done, when I try this in my compiler I get tons, yes tons, of errors, the primary error is redefinition of DTCodes.
struct DTC{<br />
TCHAR *Code;<br />
TCHAR *Description;<br />
TCHAR *Defined;<br />
int nDefined;<br />
int nIndex;<br />
};<br />
<br />
DTC *DTCodes = new DTCodes [0x4000];<br />
I also tried this way:
<br />
struct DTC{<br />
TCHAR *Code;<br />
TCHAR *Description;<br />
TCHAR *Defined;<br />
int nDefined;<br />
int nIndex;<br />
}DTCodes;<br />
<br />
DTC *DTCodes = new DTCodes [0x4000];<br />
What am I doing wrong?
Tom
|
|
|
|
|
jonsey29847 wrote: DTC *DTCodes = new DTCodes [0x4000];
should be
DTC *DTCodes = new DTC[0x4000];
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
OK, I think part of my problem is I am getting an Undeclared Identifier new error, new.h is not in my include subdirectory .
|
|
|
|
|
Is this C or C++ code?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I assumed (oops) it was C++ but no its C.
|
|
|
|
|
There's no "new" in C You can use malloc()/free() though.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yes indeed there is no new. Tonight I will try malloc()/free().
Thanks
|
|
|
|