|
I'm not quite sure exactly what you're asking, but I'll address the particular question you asked earlier in the post:
Anonymous wrote:
In allocating memory dynamically in an application either globally or in a class-specific scope, how does a person know what is actually happening in the "pool called the free store"?
Basically, at that point the operating system is giving you memory from the available ram on the system (called somewhat generically 'free-store') and returning an address to that ram (that address being a relative address, not an absolute). You as the programmer shouldn't have to worry about 'what happens' in the pool. Theoretically, nothing should 'happen' to that memory at all, except that it's now allocated to your particular process, and the operating system more than likely marks it as such so other processes (naturally) don't get ahold of it.
Now, to address some other stuff you loosely talked about, such as allocating a c++ class and automatic calling of a constructor-- those things have little to do with the 'free-store' but have a lot to do with the methodology of a c++ program. Don't allow the text: "when new is used to allocate memory for a C++ class object, the object's constructor is called after the memory is allocated" confuse you. The two things happening in the description have nothing to do with eachother (technically). If I instantiate a c++ object (class) its constructor is automatically called. If I do the same thing using the NEW operator, then its constructor is automatically called. The only difference is that the 'new' operator dynamically allocates the memory space for the new class on the heap, and then calls a constructor. If I allocate 'int' or 'char' or 'float' with the 'new' operator, the same thing occurs on the free-store (as it's called), but no constructors are called because they're not c++ classes but base data types.
Does this help at all?
Paul Oss
|
|
|
|
|
The amount of memory in the free store really depends on your memory manager. When you call new, the default memory manager is the C-runtime libraries. These libraries allocate a page of memory, and then dish out pointers to you as you need it. When you call delete that memory is returned to the store. It really does not matter how much memory is available in the store as you could use a memory manager that does things completely differently. In fact you could write your own memory manager and over load the new operator to faciliate this yourself.
What I would recommend is that you become very comfortable with the interface that C++ has supplied to allocate memory (new and delete) and move on from there.
C++ does not really supply a clean way to report how much memory has been allocated to a specific pointer. It is up to the developer to manage these sizes. If you allocate memory for an array of bytes with new like this:
<br />
new BYTE[100];<br />
you will get 100 bytes. If you want to pass that pointer to a function call, and that function needs to know how much memory is in that buffer, you will need to pass the 100 in as well.
Objects created on the stack can use the sizeof() operator. This is a compile time feature that will report the number of bytes in a particular object or variable. But beware if you try this:
<br />
Object *obj = new Object;<br />
int size = sizeof(obj);<br />
size will equal 4 (or the size of the pointers on your system), because you are requesting the size of the pointer to the object rather than the object itself.
Like Christian already posted, if you dont want to leak memory, then make sure you match each new with a delete, and each new[] with a delete[]. There are tricks however to help your memory management work a little smoother. C++ has a few template classes called auto_ptr or smart pointers. Another technique that you may want to look into is reference counting. This is a technique that COM uses exensively.
I hope I answered some of your questions, I am not quite sure what all of them were. If you have any others feel free to ask.
Good luck
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
Paul Watt (kilowatt) wrote:
C++ has a few template classes called auto_ptr or smart pointers.
C++ currently has one smart pointer AFAIK, with more to come in the next standard. It's probably a good thing to know about, but it's important to know how it's going to behave before using it.
Christian
Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002
During last 10 years, with invention of VB and similar programming environments, every ill-educated moron became able to develop software. - Alex E. - 12-Sept-2002
|
|
|
|
|
Christian Graus, Paul Oss, and Paul Watt,
Thank you for the tremendous response (I am the original anonymous that asked). The information (and background) that you provided is exactly what I was looking for, this helped alot.
I will experiment with the new and delete operators in simple, controlled situations to gain insight.
|
|
|
|
|
If anyone can point me to an example of how to make tracking tooltips work in a CControlBar, I will be eternally grateful!
|
|
|
|
|
if I understand correctly, you need to handle the message TTN_NEEDTEXT in a a CWnd window.
Max.
|
|
|
|
|
Say my MDI Document has 3 views. Whenever a File New is done 3 views are created . I want to be able to Tile all the three views during this time .
How can do this ?
|
|
|
|
|
make a call to MDITile.
cheers,
-B
|
|
|
|
|
how can I hide/show - programatically - the Windows clock in the system tray?
thanks!
|
|
|
|
|
I am trying to open a dialog box from my menu. I realize I need a message handler function, but need to know how to call the dialog box and have it open. Any coding ideas would really be appreciated.
|
|
|
|
|
If you want a modal dialog box, you can simply use ::DialogBox. If you want a modeless dialog use ::CreateDialog. In either case you will create a DialogProc function handler instead of a WndProc function handler (There is a difference). You will pass these functions into your function when you create the dialog.
If you create a modeless dialog you will need to use the function ::IsDialogMessage in order to dispatch the messages if you want your modeless dialog to handle tabs and arrow keys like other dialogs.
Good Luck
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
If you're using MFC, then all you need to do is create an instance of your dialog box, and call it's 'DoModal' function.
Christian
Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002
During last 10 years, with invention of VB and similar programming environments, every ill-educated moron became able to develop software. - Alex E. - 12-Sept-2002
|
|
|
|
|
I've searched quite a bit on this forum for the ways to terminate a process, in most case people obtain a HWND by calling ::FindWindow then get the process ID through the HWND, and kill the process.
Now my problem is that my program does not have a window, and suppose I do not know its file name either at this point, I do, however, have its HINSTANCE which was returned by the original ::ShellExecute call(that's how I launched this process). If in some ugly case this application gone frozen, is there a good way to terminate it?
|
|
|
|
|
Bin wrote:
I do, however, have its HINSTANCE
Are you sure? MSDN describes that HINSTANCE as nothing but a return value to be casted for an integer.
Unless you're using a verb, you may try CreateProcess instead of ShellExecute .
rechi
|
|
|
|
|
When I try to compile this piece of code
#include <cstddef>
#include <vector>
class klasa
{
char data[100];
public:
void* operator new (size_t)
{
return ::new klasa;
}
void operator delete (void* pt)
{
if (pt == 0) return;
::delete(pt);
}
};
void main()
{
std::vector <klasa> kontejner;
klasa k;
kontejner.push_back(k);
}
I got compiler error:
d:\program files\microsoft visual studio\vc98\include\xmemory(34) : error C2660: 'new' : function does not take 2 parameters
d:\program files\microsoft visual studio\vc98\include\xmemory(66) : see reference to function template instantiation 'void __cdecl std::_Construct(class klasa *,const class klasa &)' being compiled
WTF is going on here?
|
|
|
|
|
My *guess* would be that there is an operator new that takes two parameters and that it is involved in the creation of a vector.
BTW, you don't need to do this:
Nemanja Trifunovic wrote:
if (pt == 0) return;
delete (0) is guarenteed to be safe.
Christian
Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002
During last 10 years, with invention of VB and similar programming environments, every ill-educated moron became able to develop software. - Alex E. - 12-Sept-2002
|
|
|
|
|
Christian Graus wrote:
My *guess* would be that there is an operator new that takes two parameters and that it is involved in the creation of a vector.
True. Operator new with two arguments is required in an allocator function. The question still is what can I do about it? What to do with this second parameter?
Christian Graus wrote:
delete (0) is guarenteed to be safe.
Yeah, I know. My original new and delete are more complicated: not just wrappers for global ones.
|
|
|
|
|
I would think your object needs to impliment operator new taking the same two parameters then.
Christian
No offense, but I don't really want to encourage the creation of another VB developer. - Larry Antram 22 Oct 2002
Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002
During last 10 years, with invention of VB and similar programming environments, every ill-educated moron became able to develop software. - Alex E. - 12-Sept-2002
|
|
|
|
|
Christian Graus wrote:
I would think your object needs to impliment operator new taking the same two parameters then.
Any idea what to do with this "extra" parameter (which is a pointer to the class type)?
|
|
|
|
|
Nope - I've never done this stuff. If it were me, I'd write the function that takes the pointer, then I'd run it and check it like crazy for any sort of leak or problem. Or I'd look in the STL source for a similar operator to see what it gets used for.
Christian
No offense, but I don't really want to encourage the creation of another VB developer. - Larry Antram 22 Oct 2002
Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002
During last 10 years, with invention of VB and similar programming environments, every ill-educated moron became able to develop software. - Alex E. - 12-Sept-2002
|
|
|
|
|
Well, I just looked at "The Book" (St Bjarne Stroustrup), and found out that this new with two arguments is so-called "placement operator" - it usually just returns the pointer that comes as second argument. Strange...
|
|
|
|
|
Unfortunately, and for reasons that I do not understand, we do not have that book at work, hence my inability to check on such details. Sounds like a winner though.
Christian
No offense, but I don't really want to encourage the creation of another VB developer. - Larry Antram 22 Oct 2002
Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002
During last 10 years, with invention of VB and similar programming environments, every ill-educated moron became able to develop software. - Alex E. - 12-Sept-2002
|
|
|
|
|
Uff, there's a couple of misunderstandings here.
void* operator new (size_t)
{
return ::new klasa;
} This is the first problem in your program. An overloaded new operator is meant to be taking care of memory allocation only: the call to the class contructor is generated automatically by the compiler. Please note that the new you provide is calling implicitly the ctor through the use of golbal ::new (altough in this case the error will go unnoticed cause kasa has a trivial ctor). Instead, write something like:
void* operator new (size_t size)
{
return ::new char[size];
} or
void* operator new (size_t size)
{
return malloc(size);
} Similarly, your overloaded delete operator should be only concerned with deallocating memory without calling (implicitly) klasa::~klasa .
Now for the second problem. Once you provide an overload for new , the compiler won't use (for the relevant class) any of the predefined global new oeprators available. In particular, it won't use the so-called placement new , whose signature is:
void* operator new (size_t size,void* pos); Placement new does not really do anything: the caller already provides the space (in pos ) where the object is to be constructed. An example of an explicit call to placement new :
void *pos;
whatever *p=new(pos)whatever; Now, placement new is extensively used by allocators in STL, and this is what the compiler is complaining about: since you overloaded new you also have to provide an overload for the placement variant:
class klasa{
...
void* operator new (size_t size,void* pos)
{
return pos;
}
}; Hope I made myself clear enough
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hello, Joaquín. Thanks for your answer.
Joaquín M López Muñoz wrote:
This is the first problem in your program. An overloaded new operator is meant to be taking care of memory allocation only: the call to the class contructor is generated automatically by the compiler. Please note that the new you provide is calling implicitly the ctor through the use of golbal ::new (altough in this case the error will go unnoticed cause kasa has a trivial ctor).
As I already wrote to Christian, my original new and delete look quite different. I replaced my code with calls to global new and delete, because I wanted to make my examlple short and clear. I am aware of the issues you are talking about.
Joaquín M López Muñoz wrote:
In particular, it won't use the so-called placement new, whose signature is:void* operator new (size_t size,void* pos);
Placement new does not really do anything: the caller already provides the space (in pos) where the object is to be constructed.
Exactly. And that's what confuses me a lot. If you take a look at the implementation of placement new and delete in <new> you will see
inline void *__cdecl operator new(size_t, void *_P)
{return (_P); }
#if _MSC_VER >= 1200
inline void __cdecl operator delete(void *, void *)
{return; }
What is this good for?
Joaquín M López Muñoz wrote:
Now, placement new is extensively used by allocators in STL, and this is what the compiler is complaining about: since you overloaded new you also have to provide an overload for the placement variant
You are 100% right. The default allocator uses placement new in function construct, and when I put this code in my class
void* operator new (size_t size,void* pos) { return pos; }
void operator delete (void*, void*) {}
everything seems to work fine.
However, I still don't understand why. What is such implementation of placement new and delete good for? I know that in some cases you can provide i.e. your custom memory pool as a second argument, but here it is not the case. Why do they use this placement new in default allocator?
|
|
|
|
|
|