Pointer strangeness

I'm now trying to really get a handel on pointers. I must admit this stuff has always been confusing to me. The code below produces an unexpected result when it is run. The last line of output is "HelloClass::memberIntPtr = -1073747936". I expected it to be "HelloClass::memberIntPtr = 1848", as it is in the previous invocation of sayHello(). My guess as to what is happening is that my use of a member variable of type string, and then assigning to that variable is resulting in and over write of the memory pointed to by HelloClass::memberPtr. Is my understanding of what's happening correct? What's the proper remedy for this situation? #include <iostream> // cout, cin #include <string> using namespace std; class HelloClass { public: HelloClass::HelloClass(); void sayHello(); /** Accessors for HelloClass::message */ void setMessage(string messageStr="This is the default setMessage message."); string getMessage(); /** Accessors for HelloClass::messagePtr */ void setMessagePtr(string messageStr="This is the default setMessagePtr message."); string getMessagePtr(); /** Accessors for HelloClass::memberInt */ void setMemberInt(int memberInt=2112); int getMemberInt(); /** Accessors for HelloClass::memberIntPtr */ void setMemberIntPtr(int memberIntPtr=1848); int getMemberIntPtr(); private: string message; string *messagePtr; int memberInt; int *memberIntPtr; }; /** Constructor: initialize all member variables. */ HelloClass::HelloClass(){ this->message = "c++bean message. Assigned in constructor."; this->messagePtr = (new string("c++bean messagePtr. Assigned in constructor.")); this->memberInt = 42; int temp = 100760; this->memberIntPtr = &temp; } /** Accessors for HelloClass::message */ void HelloClass::setMessage(string messageStr){ this->message = messageStr; } string HelloClass::getMessage(){ return this->message; } /** Accessors for HelloClass::messagePtr */ void HelloClass::setMessagePtr(string messageStr){ this->messagePtr = new string(messageStr); } string HelloClass::getMessagePtr(){ return *this->messagePtr; } /** Accessors for HelloClass::memberInt */ void HelloClass::setMemberInt(int memberInt){ this->memberInt = memberInt; } int HelloClass::getMemberInt(){ return this->memberInt; } /** Accessors for HelloClass::memberIntPtr */ void HelloClass::setMemberIntPtr(int memberIntPtr){ this->memberIntPtr = &memberIntPtr; } int HelloClass::getMemberIntPtr(){ return *this->memberIntPtr; } /** Output the properties of HelloClass*/ void HelloClass::sayHello() { cout << "HelloClass::message = " << this->getMessage() << endl; cout << "HelloClass::messagePtr = " << this->getMessagePtr() << endl; cout << "HelloClass::memberInt = " << this->getMemberInt() << endl; cout << "HelloClass::memberIntPtr = " << this->getMemberIntPtr() << endl; cout << "___________________________" << endl; } main() { HelloClass h; h.sayHello(); h.setMessage(); h.setMessagePtr(); h.setMemberInt(); h.setMemberIntPtr(); h.sayHello(); h.setMessage("User defined \"Hello World\" message."); h.sayHello(); return 0; }

Remember that tmp is an automatic variable. When you exit the HelloClass constructor, the storage for tmp is released and may (or let's say will be) used in another function. Automatic variables are fundamental to C and C++. Any variable you define within the scope of a function that does not have the static keyword is an automatic variable, and has block scope. Pointers are very simple, they are simply data types that hold a memory address. char *s = "abc"; s will contain the address of a 4 byte chunk of memory containing 'a' 'b' 'c' '\0' string *str = new string("abc"); Similarly, str will contain the address of a string class that you have allocated with the new operator. Note that "string" is a C++ class, and has overhead, such as constructors, destructors, manipulation functions, and several variables as well as a pointer to the actual data. Let's get back to pointers. In the above example, str points to a string class. Now, let's change it a bit. str = new string("def"); In this case, we have replaced the existing pointer value with a new one, thus causing a memory leak. That is because we did not delete the space for the old value. Unlike Java, neither C nor C++ will automatically reclaim unused allocated memory. Java has a builtin garbage collection system. So, as a C or C++ programmer, you need to make sure that memory you allocate is reclaimed. Within a class, that may be done in a destructor or in your case, HelloClass::setMessagePtr should check this->messagePtr to see if it already contains a pointer. Also, you do not need to use this-> in a class member function, it is assumed. I hope that the above information has been useful.

On Mon, 31 Mar 2003, Jerry Feldman wrote:
Remember that tmp is an automatic variable. When you exit the HelloClass constructor, the storage for tmp is released and may (or let's say will be) used in another function. Automatic variables are fundamental to C and C++. Any variable you define within the scope of a function that does not have the static keyword is an automatic variable, and has block scope. Ok, now I see what's going on. My pointing to temp with memberIntPtr doesn't place a 'handle' on so when temp is gone, that memory is up for grabs, and I end up pointing at someone elses data. The reason I did that is because I couldn't figure out how to directly point to the same value.
I guess, from what you're saying, that isn't something I should be doing in the first place.
Pointers are very simple, they are simply data types that hold a memory address.
char *s = "abc"; s will contain the address of a 4 byte chunk of memory containing 'a' 'b' 'c' '\0'
The part about pointing to 'a' is a helpful refresher. I guess I already knew it was pointing to the beginning of the 'string', but I wasn't thinking in terms of the data it was actually referring to. It makes it more real to think about it actually being 'a'.
string *str = new string("abc"); Similarly, str will contain the address of a string class that you have allocated with the new operator.
Note that "string" is a C++ class, and has overhead, such as constructors, destructors, manipulation functions, and several variables as well as a pointer to the actual data.
I'll keep that in mind. The same is true in Java, but Java programmers don't worry about efficiency. That's someone elses job, and sun Microsystems likes it that way.
Let's get back to pointers. In the above example, str points to a string class. Now, let's change it a bit. str = new string("def");
In this case, we have replaced the existing pointer value with a new one, thus causing a memory leak. That is because we did not delete the space for the old value. Unlike Java, neither C nor C++ will automatically reclaim unused allocated memory. Java has a builtin garbage collection system. So, as a C or C++ programmer, you need to make sure that memory you allocate is reclaimed.
A bit of (X)Emacs and Lisp heritage there in the Java GC. I'm under the impression that QT has strings that clean up after themselves, but that may not be the silver bullet it sounds like.
Within a class, that may be done in a destructor or in your case, HelloClass::setMessagePtr should check this->messagePtr to see if it already contains a pointer.
This is part of the reason I'm playing around with this. It's the part of C/C++ that I always avoided, and it's why Java was some much easier for me to learn.
Also, you do not need to use this-> in a class member function, it is assumed.
Ya, I know, it bugs a lot of peple, but I do that in Java too. It helps me understand my code. It also primes the code completion magic in JBuilder. The same works for KDevelop, but KDevelop's code completion is kilometers behind JBuilder.
I hope that the above information has been useful.
Indeed. I guess the most important thing I got out of it is that pointers don't control the memory they point to. I guess I knew that at one point, I just got used to Java's way of keeping track of references. The same can be done in C++, but we have to do it ourselves. If I want to keep the data in a variable from getting zapped, I have to keep the variable alive(in scope, or static). Is that pretty much a correct statement? BTW, I'm using pine for this message, which I rarely do. If it is a bit strangely formatted, that will explain it. STH

On Monday 31 March 2003 10:08 am, Steven T. Hatton wrote:
I hope that the above information has been useful.
Indeed. I guess the most important thing I got out of it is that pointers don't control the memory they point to. I guess I knew that at one point, I just got used to Java's way of keeping track of references. The same can be done in C++, but we have to do it ourselves. If I want to keep the data in a variable from getting zapped, I have to keep the variable alive(in scope, or static). Is that pretty much a correct statement?
Let me refine this. Upon reflection, I realized what I said is only accurate regarding fundamental types. Objects are the other way around. I have to tell them to go away explicitly, or they just sit there and take space. And if I don't to that before I remove the last pointer to the object, then I have not way to access the destructor.
STH

On Mon, 31 Mar 2003 10:48:43 -0500 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
Let me refine this. Upon reflection, I realized what I said is only accurate regarding fundamental types. Objects are the other way around. I have to tell them to go away explicitly, or they just sit there and take space. And if I don't to that before I remove the last pointer to the object, then I have not way to access the destructor. When a variable goes out of scope, a destructor is called. I suggest that when you are learning C++, start by writing your own classes. Then, once you understand the language, then start using the STL and other class libraries. The STL has a large number of container types, such as vector, link lists, trees et. al. But, while these are great to use, the details of the implementation are hidden. That's not a bad thing, but when you are learning a language you are not learning some of the finer points of that language. For instance, a person who does not know Java can pick up JBuilder and build some programs, but not lean how to write Java code. In C++, you should first lean the basics of the language, then move up to writing some classes. Then learn multiple inheritance and templates. The problem is the time tradeoff. Most of us want to be productive and get something out the door, or use the skills on the job.
-- -- Gerald Feldman <gfeldman@attbi.com> Boston Computer Solutions and Consulting ICQ#156300 PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

On Monday 31 March 2003 01:03 pm, Jerry Feldman wrote:
On Mon, 31 Mar 2003 10:48:43 -0500
"Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
Let me refine this. Upon reflection, I realized what I said is only accurate regarding fundamental types. Objects are the other way around. I have to tell them to go away explicitly, or they just sit there and take space. And if I don't to that before I remove the last pointer to the object, then I have not way to access the destructor.
When a variable goes out of scope, a destructor is called. I suggest that when you are learning C++, start by writing your own classes. Then, once you understand the language, then start using the STL and other class libraries. The STL has a large number of container types, such as vector, link lists, trees et. al. But, while these are great to use, the details of the implementation are hidden. That's not a bad thing, but when you are learning a language you are not learning some of the finer points of that language. For instance, a person who does not know Java can pick up JBuilder and build some programs, but not lean how to write Java code.
This is true to some extent, but I've found the GUI builders, and other wizards are often more trouble than they're worth. I tend to use them to generate samples that I look at to figure out how to accomplish what I really want. The one place were JBuilder did prove really helpful was in getting me started with servlets. The Apache Tomcat is configured and ready to run out of the box. I was able to click on new servlet, build, run, and I had a working servlet. But that doesn't do much on its own. The biggest advantage in using something like JBuilder is that it helps organize the project, and provides quick access to resources such as class browsers, code completion, on-line documentation, etc. But the Java world in general is oriented that way.
In C++, you should first lean the basics of the language, then move up to writing some classes.
Part of the problem is I'm re-learning. There was a time I knew C fairly well. Not to say I was a good C programmer, I just had a pretty complete understanding of the basics of the language. I do need to continue reading up on C++. Unfortunately, I don't know of anything for C++ equivalent to K&R, Cooper's Pascal book, Arnold, Gosling, and Holmes's Java book, or Flanagan's JavaScript book. Then again, I haven't been looking. I'm kind of limited in what I can buy right now. I also haven't been able to focus on the language as much as I would like due to the problems I've been having with my KDevelop setup. Hopefully I have that stabilized, and won't need to mess with it for a while. I'll have to go back and forth between using KDevelop and XEmacs while learning C++. KDevelop and the QT Designer do provide a useful framework. But as you've pointed out, they don't teach the language. That's why I cracked open XEmacs and tried to write a hello world. When I got the deprication messages I tried to find out how I should be writing a hello world. The books I have were no help. I was using the example code from these books. That's when I came on this list. There has to be a better way of getting started than this. Are there any good books that teach C++ using these new standard libraries? I.e., a book that starts with the kind of hello world I ended up with after a few iterations?
Then learn multiple inheritance and templates. The problem is the time tradeoff. Most of us want to be productive and get something out the door, or use the skills on the job.
That can be quite frustrating. It's not like the good old days when someone could ask you how long it will take you to plough the field. You could go ask your grand dad how long it should take. Now people want to know how long it will take you to do something that no one knows how to do, or at least you don't know how to do it. If you knew, it would be done! And then there's doing things correctly. That's where really knowing the language, and all the nuances comes in.
-- -- Gerald Feldman <gfeldman@attbi.com> Boston Computer Solutions and Consulting ICQ#156300 PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

On Tue, 1 Apr 2003 07:28:28 -0500 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
I'll have to go back and forth between using KDevelop and XEmacs while
learning C++. KDevelop and the QT Designer do provide a useful framework. But as you've pointed out, they don't teach the language. That's why I cracked open XEmacs and tried to write a hello world. When I got the deprication messages I tried to find out how I should be writing a hello world. The books I have were no help. I was using the example code from these books. That's when I came on this list.
There has to be a better way of getting started than this. Are there any good books that teach C++ using these new standard libraries? I.e., a book that starts with the kind of hello world I ended up with after a few iterations?
Then learn multiple inheritance and templates. The problem is the time tradeoff. Most of us want to be productive and get something out the door, or use the skills on the job.
That can be quite frustrating. It's not like the good old days when someone could ask you how long it will take you to plough the field. You could go ask your grand dad how long it should take. Now people want to know how long it will take you to do something that no one knows how to do, or at least you don't know how to do it. If you knew, it would be done!
And then there's doing things correctly. That's where really knowing the language, and all the nuances comes in. The Deitel books are very good. I have the C version. We don't use that at Northeastern because the book was too difficult for the students. Another book I found useful several years ago was The C++ Primer. I was in a C++ shop with some very complex code and needed to upgrade my skills quickly. Even the old version that I have has proven useful. Both the Deitel book (C++ How to Program) and the C++ Primer are continually updated. If you can afford both books go for it, but if you can't, go to a bookstore and try reading a bit. The book we use for C at Northeastern is C Programming, A Modern Approach. He does not have a C++ book, but here is a URL of his recommendations: http://knking.com/recbooks/cpp.html
Read his comment on C++ Primer. -- -- Gerald Feldman <gfeldman@attbi.com> Boston Computer Solutions and Consulting ICQ#156300 PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

<massive snip>
There has to be a better way of getting started than this. Are there any good books that teach C++ using these new standard libraries? I.e., a book that starts with the kind of hello world I ended up with after a few iterations?
<massive snip> I've been happy with these two C++ textbooks: Deitel's "C++ How to Program" and Bruce Eckel's "Thinking in C++" Here's Bruce Eckel's page from which you can download free books: http://www.mindview.net/Books The Classroom CDROMs are a good way to learn as well. Cheers

On Tuesday 01 April 2003 08:02 am, Jerry Feldman wrote:
On Tue, 1 Apr 2003 07:28:28 -0500
"Steven T. Hatton" <hattons@globalsymmetry.com> wrote: ...
There has to be a better way of getting started than this. Are there any good books that teach C++ using these new standard libraries? I.e., a book that starts with the kind of hello world I ended up with after a few iterations? ... And then there's doing things correctly. That's where really knowing the language, and all the nuances comes in.
The Deitel books are very good. I have the C version.
Please don't mistake the following question as my ignoring your advice regarding Deitel. His books have been recommended by many people whom I hold in high regard. I may purchase his Book, and the Primer. With that said, please allow me to elaborate on what I am looking for in a C++ book. I am looking for a self-contained presentation of the language that introduces the components of the language in a mathematical spirit. That is, as Spinoza attempted with Ethics, I am looking for 'C++ presented in geometric order'. I want to see definitions of what constitutes an identifier, a key word, an expression, a function, a class, etc., _before_ the concepts are used. The exception might be the inclusion of a "Tutorial Introduction" similar to the one found in K&R. Did K&R ever write a C++ book? ;-)
We don't use that at Northeastern because the book was too difficult for the students. I will never understand how that works. I often find the books that the other students find 'easy' to be so full of fluff that I lose focus and interest. When I took Pascal, I read Cooper. When I took C I read K&R. When I took C++ I floundered around looking for that essential presentation, which I didn't find. Perhaps Deitel's is that book. I suspect the book I'm looking for is no more than 400 pages, and does not have many, if any, 'exercises'. IOW, I'm looking for an exposition, more than a classroom text.
I should observe that I think differently than most people. For example, I just finished chapter 4 of Ellis & Stroustrup. The one part that I believe I clearly understood was the part of 4.8 instroduced with the sentence "This may seem backwards at first." That part made perfect sense to me. You can't point at something that ain't there. I kind of understood the rest of the chapter, but chalked most of it up to a once over exposure to ideas I will need to review after (re)learning more of the language.
Another book I found useful several years ago was The C++ Primer. I was in a C++ shop with some very complex code and needed to upgrade my skills quickly.
I'm wondering if this would be a good choice: "C++ Programming Language, The: Special Edition , Third Edition" http://www.awprofessional.com/catalog/product.asp?product_id={DD9AAB03-6085-4008-A260-09D1F7592386} If it's similar to Ellis & Stroustrup's Book, it's not what I'm looking for.
Gerald Feldman <gfeldman@attbi.com>
STH STH

I am looking for a self-contained presentation of the language that introduces the components of the language in a mathematical spirit.
Appendix A of the Stroustrup book contains a complete grammar of the language. If you consider that to be a useful tool for learning a language, you go right ahead and digest it!
I'm wondering if this would be a good choice: "C++ Programming Language, The: Special Edition , Third Edition" http://www.awprofessional.com/catalog/product.asp?product_id={DD9AAB03-6085 -4008-A260-09D1F7592386} If it's similar to Ellis & Stroustrup's Book, it's not what I'm looking for.
I've not been following the thread, so I thought this book had been discussed. It's the definitive tome, the K&R of C++. It's the book I mention above, with the grammar in Appendix A. I have the paperback version which has a different cover and ISBN number, but the table of contents is identical to my copy. It's a pig to read - very heavy going - but if you're after the definitive work on the language with every single feature[*] guaranteed to be covered, that's the book to have. [*] GNU GCC extensions not included. :o) -- "...our desktop is falling behind stability-wise and feature wise to KDE ...when I went to Mexico in December to the facility where we launched gnome, they had all switched to KDE3." - Miguel de Icaza, March 2003

On Saturday 05 April 2003 12:23 am, Derek Fountain wrote:
I am looking for a self-contained presentation of the language that introduces the components of the language in a mathematical spirit.
Appendix A of the Stroustrup book contains a complete grammar of the language. If you consider that to be a useful tool for learning a language, you go right ahead and digest it!
Actually, I did find the grammar in K&R to be worth reading through. I've given serious thought to transcribing the grammar in Ellis and Stroustrup into a hyperlinked form and trying to flesh it out with links, both internalm, and to further discussions and examples. I have to agree, the grammar itself is not a very effective introductory pedagogical tool.
I've not been following the thread, so I thought this book had been discussed. It's the definitive tome, the K&R of C++. It's the book I mention above, with the grammar in Appendix A. I have the paperback version which has a different cover and ISBN number, but the table of contents is identical to my copy.
It's a pig to read - very heavy going - but if you're after the definitive work on the language with every single feature[*] guaranteed to be covered, that's the book to have.
My problem with the Ellis and Stroustrup book has to do with the amount of attention given to the whys of language design, and the extensive comparison and contrast with C. It also assumes the reader is fairly comfortable with C, which I am not - thought I am not completely at a loss. I just hope his SE is a bit more focused on C++, rather than on the place of C++ in the C programmer's life. I realize you mentioned this book earlier. It doesn't look to be the 400 page exposition I was dreaming about. To some extent, I'm just rambling about what I think make a good 'definitive' language book. I was also trying to pick up the discussion since I've been very distracted with getting my system in some semblence of order. I do believe this horse is about ready fo the glue factory. I'm working on another message which probably stands to go a bit further. TTTT, Ira Pohl's Object-Oriented Programming Using C++ looks like a modest approximation to what I'm seeking. Since I already have it, the price can't be beat.
[*] GNU GCC extensions not included. :o)
I have the sense what I really want is the standard C++ library reference, which seems to be treated in Stroustrup's SE. Actually, I think what sold me on the Stroustrup Book was the reference to Eric Blood-Axe. {:-)> STH

On Saturday 05 April 2003 02:24 am, Steven T. Hatton wrote:
I have the sense what I really want is the standard C++ library reference, which seems to be treated in Stroustrup's SE. Actually, I think what sold me on the Stroustrup Book was the reference to Eric Blood-Axe. {:-)>
STH
Please note: my comment about Eric Blood-Axe was a purely literary comment, and has absolutely nothing to do with the unfortunate circumstances in Iraq. I don't want to get into politics on this list, but I realize in the current world situation, my off the cuff comment could be missconstrued. STH

On Monday 31 March 2003 01:03 pm, Jerry Feldman wrote:
On Mon, 31 Mar 2003 10:48:43 -0500
"Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
Let me refine this. Upon reflection, I realized what I said is only accurate regarding fundamental types. Objects are the other way around. I have to tell them to go away explicitly, or they just sit there and take space. And if I don't to that before I remove the last pointer to the object, then I have not way to access the destructor.
When a variable goes out of scope, a destructor is called.
That is a variable. What about anonymous objects? I believe such a concept is meaningful in C++, e.g., the elements of a linked list. If I start removing elements form such a list without explicitly destroying them, I could end up with object occupying memory, yet having no reference to them withing my program. Is this not true? If you've been following any of the saga of my KDE/QT/KDevelop woes, you will understand that I haven't had a lot of time to follow up on these topics. I did get to thinking about your comments regarding defining a class in the header, and it's methods in the 'source' file. There are a few things I'm not sure of regarding classes. With time, and further reading, I suspect these will become clear, but it probably doesn't hurt to mention them. As I understand things, the class definion itself is in a favored position to go on the stack rather than the heap. This could mean different things depending on the details. I assume the static members would only appear once in the run-time image. If we say a method gets put on the stack, what we really mean is it's local variables and return pointer are placed on the stack. Methods defined within the body of the class definions are default /inline/ meaning they 'should' go on the stack. My understanding is that member variables cannot be initialized within the class definiton. Functions can, however, be completely defined within the class definition. And here again, is a point of some confusion. Experimentation indicates to me that classes *are* initialized by their default constructor when declared in the body of the class declaration. So class MyClass { private: MyMember mm; int myInt; } If MyMember has an initializer in its constructor, its variables can be initialized by the implicit invocation of the constructor resulting from the declaration. myInt, however will not be initialized, and cannot be initialized at the point shown above. Part of what I'm trying to get a handle on is the way a class instance and it's members will be represented in memory. It seems possible, if not likely, some parts may go on the stack while other perts go in the heap. In particular, it seems member variables might go on the heap. The original question that started me down this road has to do with the actual size of a pointer to an object of a given type, and also the amount by which such a pointer will be incremented with, for example ptr++. Are these notions about pointer size and pointer incrementation easy to explain?
Gerald Feldman <gfeldman@attbi.com>
STH

Steven T. Hatton wrote:
When a variable goes out of scope, a destructor is called.
That is a variable. What about anonymous objects? I believe such a concept is meaningful in C++, e.g., the elements of a linked list.
Yes, but you should always keep a pointer to an object until it is deleted. It is possible to create an anonymous object (just use new X(); without an assignment) or to throw away a pointer (just create an object with new in a function and don't pass the pointer value when the function finishes), but these are bad practices. Unfortunately C++ doesn't have any garbage collection like java does, though you could look at the auto_ptr class. Distinguish between 'anonymous object', which is not used as a term in C++ AFAIK, and 'anonymous class', which is. For example, below, ratio is an object of an anonymous class, used together with operator overloading to create a local object that behaves like a function. This technique is a bit obscure, but becomes useful in the Standard Template Library. #include<iostream> using namespace std; int main(){ struct { double operator()( double x, double y ){ return x / y; } } ratio; double d = ratio( 1, 2 ); cout << d << endl; cout << 1 / 2 << endl; exit( 0 ); }
If I start removing elements form such a list without explicitly destroying them, I could end up with object occupying memory, yet having no reference to them withing my program. Is this not true?
Yes, which is why you should handle this carefully. For example, you could use a class to handle the linked list, with a member function for adding/removing elements. Then the member function is responsible for tidying up the heap. Here, I would use the STL or Qt version of the linked list, which already handles such things safely.
If you've been following any of the saga of my KDE/QT/KDevelop woes, you will understand that I haven't had a lot of time to follow up on these topics. I did get to thinking about your comments regarding defining a class in the header, and it's methods in the 'source' file. There are a few things I'm not sure of regarding classes. With time, and further reading, I suspect these will become clear, but it probably doesn't hurt to mention them.
As I understand things, the class definion itself is in a favored position to go on the stack rather than the heap. This could mean different things depending on the details. I assume the static members would only appear once in the run-time image. If we say a method gets put on the stack, what we really mean is it's local variables and return pointer are placed on the stack. Methods defined within the body of the class definions are default /inline/ meaning they 'should' go on the stack.
The separation between class declaration and class definition affects compiling rather than where a class is defined. In fact, you can't define a class on the heap, only objects of the class. Your code may contain more than one copy of a class member function definition, but only as an accident of the way it was compiled. If you separate the declaration from the definition by using a header file, you don't get copies of member functions in the object code.
My understanding is that member variables cannot be initialized within the class definiton.
At least, not within the class declaration. This wouldn't make sense except for static member variables because they take different values for different classes. Static member variables can be initialised outside the class declaration with a statement like double A::pi = 3.1415926536 I think you can initialise ints withing the declaration. Usually, you would only initialise static consts and not in the header file (otherwise you'll get an error if you read the header twice). Functions can, however, be completely defined within the
class definition.
Yes, but their local variables are not defined until the member function is called and each object gets it's own copy of a nonstatic member function's variables. And here again, is a point of some confusion.
Experimentation indicates to me that classes *are* initialized by their default constructor when declared in the body of the class declaration. So
class MyClass { private: MyMember mm; int myInt; }
If MyMember has an initializer in its constructor, its variables can be initialized by the implicit invocation of the constructor resulting from the declaration. myInt, however will not be initialized, and cannot be initialized at the point shown above.
Yes: MyMember is an object but MyClass is a class.
Part of what I'm trying to get a handle on is the way a class instance and it's members will be represented in memory. It seems possible, if not likely, some parts may go on the stack while other perts go in the heap. In particular, it seems member variables might go on the heap.
It's probably not useful to think about stack and heap unless you're writing your own compiler. Think instead that anything created with new must be destroyed by delete; otherwise the thing gets destroyed when it is out of scope.
The original question that started me down this road has to do with the actual size of a pointer to an object of a given type, and also the amount by which such a pointer will be incremented with, for example ptr++.
ptr++ will be incremented by the size of the type to which ptr is a pointer.
Are these notions about pointer size and pointer incrementation easy to explain?
Relatively. The compiler knows the size of an object of any given type and know the type of any given pointer; so given that ptr has type *my_type, ptr++ will add sizeof( my_type ) to ptr. This fact is only useful, of course, if you know that an array or my_type occupies a contiguous area of memory in which each my_type object occupies sizeof(my_type).
STH
-- JDL

On Sun, 6 Apr 2003 10:09:41 -0500 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
That is a variable. What about anonymous objects? I believe such a concept is meaningful in C++, e.g., the elements of a linked list. If I start removing elements form such a list without explicitly destroying them, I could end up with object occupying memory, yet having no reference to them withing my program. Is this not true? This is what is called a memory leak.
There are a few things I'm not sure of regarding classes. With time, and further reading, I suspect these will become clear, but it probably doesn't hurt to mention them.
As I understand things, the class definion itself is in a favored position to go on the stack rather than the heap. This could mean different things depending on the details. I assume the static members would only appear once in the run-time image. If we say a method gets put on the stack, what we really mean is it's local variables and return pointer are placed on the stack. Methods defined within the body of the class definions are default /inline/ meaning they 'should' go on the stack. A class definition does not take up any memory, just as a structure definition does not. It is the instance of a class that allocates memory. If you allocate a class as an automatic variable, that instance will be allocated in the stack. If you use the new operator, it will be allocated on the heap. remember, that all objects allocated on the stack are implicitly destroyed when the function returns to the caller.
My understanding is that member variables cannot be initialized within the class definiton. Functions can, however, be completely defined within the class definition. And here again, is a point of some confusion. Experimentation indicates to me that classes *are* initialized by their default constructor when declared in the body of the class declaration. So
class MyClass { private: MyMember mm; int myInt; }
If MyMember has an initializer in its constructor, its variables can be initialized by the implicit invocation of the constructor resulting from the declaration. myInt, however will not be initialized, and cannot be initialized at the point shown above.
Part of what I'm trying to get a handle on is the way a class instance and it's members will be represented in memory. It seems possible, if not likely, some parts may go on the stack while other perts go in the heap. In particular, it seems member variables might go on the heap. The original question that started me down this road has to do with the actual size of a pointer to an object of a given type, and also the amount by which such a pointer will be incremented with, for example ptr++.
Are these notions about pointer size and pointer incrementation easy to explain? non-static and non-constant class members are not initialized in the class, but are normally initialized by the constructor for that class, but they can be initialized with a member initialization list. Using above class: inline MyClass::MyClass():myInt(0) {}
WRT: Pointers: int i[10]; int *p; To use the pointer, p to step through the array: for(p = i;p < &i[10]; p++) { *p = <some expression>; } Note that &i[10] is a constant expression and will be evaluated at compile time. The expression, p++, is a postincrement of p, and on a system with a 32 bit int, the address contained in p will be incremented by 4. However, when you use a modern compiler, subscripts are more efficient than pointers because the compiler can more easily figure out what you are doing and generate some more efficient code. The bottom line, is that when you are doing pointer arithmetic, the size of the object that pointer points to is taken into account: So, as above, p + 1 effectively adds 4 to p. -- -- Gerald Feldman <gfeldman@attbi.com> Boston Computer Solutions and Consulting ICQ#156300 PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

On Sunday 06 April 2003 01:54 pm, Jerry Feldman wrote:
On Sun, 6 Apr 2003 10:09:41 -0500
"Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
A class definition does not take up any memory, just as a structure definition does not. It is the instance of a class that allocates memory.
Yes, my statement doesn't really make a lot of sense now that I think about it. What matters is not how the class is defined, but rather how objects of that type are instantiated.
If you allocate a class as an automatic variable, that instance will be allocated in the stack.
I'm still fumbling about with some of these notions. The /new/ operator returns a pointer to an object of the class upon which it was called. If I simply declare a variable of that type, it seems to be created, and the default constructor seems to be called to initialize its members. But it would seem this is not synonymous with an implicit invocation of new. For one thing, the object is accessible through a variable name rather than a pointer reference. Now if I do something like void doThis() { MyClass mc; mc.myMethod(); } I implicitly create an instance of MyClass and set the variable mc to hold that object. If, in turn, MyClass has a member variable of some object type, that is created in a similar manner. I assume this member object is destroyed when its owner is destroyed. Correct? Would it also be correct to assume these are created on the stack rather than the heap?
If you use the new operator, it will be allocated on the heap. remember, that all objects allocated on the stack are implicitly destroyed when the function returns to the caller.
I believe I have figured out part of the problem I referred to earlier regarding the difference between member variables of derived types and member variables which are pointers to objects of the same type. I failed to realize that /new/ returns a pointer. I was therefore gettng strange results when I attempted things such as this->mm = new MyMember(); But this raises an interesting question. How would I do such a thing? If I have member pointers to objects, then it is incumbent upon me to be sure they are destroyed when they are no longer necessary. If I use member variables, and somehow assign to them within a function call, it would seem these would be destroyed when the function returned, which is very likely not what I would want. This sho' anin't Java. ;-) Here's an example of what I'm talking about. I have a class derived from QTextEdit which I wanted to hold as a member variable of a manager class. I was taking your advice about the overhead of using pointers (though it's probably insignificant in this context.) I was also thinking it would be cleaner to manage in the sense described above. The problem I encountered is that I could not figure out a way to pass /this/ as an argument from within the constructor when instantiating the children. I'm trying to have another go at that, but it's going to take me a bit to reconstruct the exact circumstances where I had the problem. I wanted to post an example, but I've been delaying sending this out for too long already.
Are these notions about pointer size and pointer incrementation easy to explain?
non-static and non-constant class members are not initialized in the class, but are normally initialized by the constructor for that class, but they can be initialized with a member initialization list. Using above class: inline MyClass::MyClass():myInt(0) {}
Hmmm. Thanks. I'll have to play with that a bit.
WRT: Pointers: int i[10]; int *p; To use the pointer, p to step through the array: for(p = i;p < &i[10]; p++) { *p = <some expression>; } Note that &i[10] is a constant expression and will be evaluated at compile time. The expression, p++, is a postincrement of p, and on a system with a 32 bit int, the address contained in p will be incremented by 4. However, when you use a modern compiler, subscripts are more efficient than pointers because the compiler can more easily figure out what you are doing and generate some more efficient code.
The bottom line, is that when you are doing pointer arithmetic, the size of the object that pointer points to is taken into account: So, as above, p + 1 effectively adds 4 to p.
I wasn't sure about the 'p + 1' part, but I did recall the part about incrementing by the 'size' of the object. My curiosity lies with the true meaning of 'size of the object'. This relates back to my awkward errant attempt to explain how memory is allocated for a class. I recall a frient of mine - who is pretty well versed in C - stated that the data in an array goes on the stack. That would mean 'p + 1' is referring to memory locations of the stack, and not the heap. This further suggests to me that an object with an array as a member would be larger than the array, and thus a pointer ptr to that class would increment by a number potentially much larger than 4. Do you see what I'm getting at?
Gerald Feldman <gfeldman@attbi.com>
STH

On Monday 07 April 2003 07:08, Steven T. Hatton wrote:
I wasn't sure about the 'p + 1' part, but I did recall the part about incrementing by the 'size' of the object. My curiosity lies with the true meaning of 'size of the object'. This relates back to my awkward errant attempt to explain how memory is allocated for a class. I recall a frient of mine - who is pretty well versed in C - stated that the data in an array goes on the stack. That would mean 'p + 1' is referring to memory locations of the stack, and not the heap.
I think you're looking too closely at details here. The C language doesn't define where things are stored, stack and heap are implementation details of the compiler, not part of the language. If you want to learn the languages quickly, I would suggest you try to take a couple of steps back and focus on the bigger picture. I don't think it's pedagogically right to get bogged down in how gcc implements things. Just a suggestion Anders

On Monday 07 April 2003 02:39 am, Anders Johansson wrote:
On Monday 07 April 2003 07:08, Steven T. Hatton wrote:
I wasn't sure about the 'p + 1' part, but I did recall the part about incrementing by the 'size' of the object. My curiosity lies with the true meaning of 'size of the object'. This relates back to my awkward errant attempt to explain how memory is allocated for a class. I recall a frient of mine - who is pretty well versed in C - stated that the data in an array goes on the stack. That would mean 'p + 1' is referring to memory locations of the stack, and not the heap.
Jerry seems to know what he's talking about. I am operating on the assumption that these things are implementation details, and what Jerry is explaining is the 'recommended' implementation. Some of my questions are simply academic curiousity. It does help me to try and formulate these questions. It causes me to think about how to express what I'm doing in technically accurate terms.
I think you're looking too closely at details here. The C language doesn't define where things are stored, stack and heap are implementation details of the compiler, not part of the language.
I believe there are a few exceptions to that, but, in general you are correct. What I'm most interested in how to manage memory, and construct runtime object graphs.
If you want to learn the languages quickly, I would suggest you try to take a couple of steps back and focus on the bigger picture. I don't think it's pedagogically right to get bogged down in how gcc implements things.
I really don't want to spend too much time on this topic, but it has its importance. For example, in security, it's important to understand how, when, and where things are loaded into memory. And as I said, it helps me think about what I'm actually doing. That is, what *is* a runtime instance of a class? Where it goes, stack or heap, isn't so important, but the distinctions between pointer, variable, reference, automatic, static, etc., are.
Just a suggestion
I will agree that it's dangerous to try to exploit implementation details of a language which are not specified in defining document. I got bit hard by that when I tried to use an example my Professor gave of how to get the lenght of a string in Pascal by playing with the 0th element. It didn't work on a PC the same way it did on the Vax.
Anders
The question remains. How big is an object? What does sizeof really mean? Also, what's the lifetime of a member variable of derived type when created as a side effect of implicit (automatic?) instantiation in a function call variable declaration? STH

On Monday 07 April 2003 09:34, Steven T. Hatton wrote:
Jerry seems to know what he's talking about.
I don't remember questioning that. I know he knows far more than I about c++
The question remains. How big is an object? What does sizeof really mean?
An object is the size of its members. Plus all objects of a class share the methods of that class. Plus possible padding bytes (don't know about that one, but C sometimes does that for structs and unions, to align the data on word boundaries. I guess c++ does the same, but I don't know). sizeof returns the size of the parameter. I think sizeof for an object returns the dynamic size of that instance. i.e. not counting the methods it shares with other objects of that class.
Also, what's the lifetime of a member variable of derived type when created as a side effect of implicit (automatic?) instantiation in a function call variable declaration?
If I understand the question, I would say from the time the function is called to the time the function returns.

On Mon, 7 Apr 2003 17:38:33 +0200 Anders Johansson <andjoh@rydsbo.net> wrote:
An object is the size of its members. Plus all objects of a class share the methods of that class. Plus possible padding bytes (don't know about that one, but C sometimes does that for structs and unions, to align the data on word boundaries. I guess c++ does the same, but I don't know).
sizeof returns the size of the parameter. I think sizeof for an object returns the dynamic size of that instance. i.e. not counting the methods it shares with other objects of that class.
Also, what's the lifetime of a member variable of derived type when created as a side effect of implicit (automatic?) instantiation in a function call variable declaration? You are correct. Structure members are generally aligned to "natural" boundaries. A 64 bit long to a 64 bit boundary, a 32 bit int to a 32 bit boundary, a double to its natural boundary. This is critically important on RISC processors as the fetching of these on an odd boundary causes a trap (and may result in a crash or a very slow fixup). On Pentium class processors, it is of less importance in that (I believe but have not explicitly tested) fetching an unaligned data element results in a slower access.
C++ classes are a bit messy because, like Java, you can have static data, constants (which in C++ are true constants not just read/only variables), non-static data members (public, protected or private), and of course class functions. I don't know the C++ rules governing the ordering of data elements within a class. In a struct, the ordering is strictly the same order (plus any fillers) the coder put them in. In C++ I have not looked at the standard as I have on C. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

On Monday 07 April 2003 11:38 am, Anders Johansson wrote:
On Monday 07 April 2003 09:34, Steven T. Hatton wrote:
The question remains. How big is an object? What does sizeof really mean?
An object is the size of its members. Plus all objects of a class share the methods of that class. Plus possible padding bytes (don't know about that one, but C sometimes does that for structs and unions, to align the data on word boundaries. I guess c++ does the same, but I don't know).
sizeof returns the size of the parameter. I think sizeof for an object returns the dynamic size of that instance. i.e. not counting the methods it shares with other objects of that class.
The reason I asked the question is that I'm not sure that every instance of a class will have the same size. If they don't, then how would the result of incrementing a pointer (ptr++ ) be calculated?
Also, what's the lifetime of a member variable of derived type when created as a side effect of implicit (automatic?) instantiation in a function call variable declaration?
If I understand the question, I would say from the time the function is called to the time the function returns.
The following code is kind of messy. It's intended to illustrate some of the pointer issuees I'm dealing with. Notice that I never explicitly instantiate tc.mc, neither in the constructor nor in any function. Nonetheless, I can call mc.output(), thereby demonstrating the constructor had been called. I intentionally omitted the initialization of int someNum to demonstrate that it is not automatically initialized. I do, however, initialize tc.mcPtr using: this->mcPtr = new MemberClass(this); That is, to demonstrate that I can use /this/ within a constructor. It also demonstrates the design issue I was mulling over when I started posting to the list. I'm not sure there is a way to accomplish a similar instantiation of a member. IOW, I'm not sure I can explicitly call a constructor and pass /this/ as an argument. I am sure that I don't know how to do so. There are five files represented in the following. testclass.h testclass.cpp memberclass.h memberclass.cpp main.cpp Two classes are defined, TestClass and MemberClass. /* testclass.h */ #ifndef TESTCLASS_H #define TESTCLASS_H #include <iostream> #include <string> #include "memberclass.h" using namespace std; class TestClass { public: TestClass(); ~TestClass(); void setOwnerMessage(char * ownerMessage="Owner Message"); void output(); void ownerOutput(); private: string message; string ownerMessage; int someNum; MemberClass mc; MemberClass * mcPtr; }; #endif /********************************/ /* testclass.cpp */ #include <iostream> #include <string> #include "testclass.h" #include "memberclass.h" using namespace std; TestClass::TestClass(){ this->message = "I am of TestClass. Assigned in the constructor"; this->ownerMessage = ""; this->mcPtr = new MemberClass(this); } TestClass::~TestClass(){ } void TestClass::setOwnerMessage(char * ownerMessage) { this->ownerMessage = ownerMessage; } void TestClass::output() { cout << this->message << endl; cout << "TestClass.someNum=" << this->someNum << endl; this->mc.output(); this->mcPtr->output(); } void TestClass::ownerOutput() { cout << "Owner Message=" << this->ownerMessage << endl; } /*******************************/ /* memberclass.h */ #ifndef MEMBERCLASS_H #define MEMBERCLASS_H #include <iostream> #include <string> using namespace std; class TestClass; class MemberClass { public: MemberClass(TestClass * owner = 0); ~MemberClass(); void output(); private: string message; TestClass * owner; }; #endif /********************************/ /* memberclass.cpp */ #include <iostream> #include <string> #include "memberclass.h" #include "testclass.h" using namespace std; MemberClass::MemberClass(TestClass * owner){ this->message = "I am of MemberClass. Assigned in the constructor"; this->owner = owner; } MemberClass::~MemberClass(){ } void MemberClass::output(){ cout << this->message << endl; if(this->owner) { this->owner->setOwnerMessage("I am the owner of a MemberClass"); this->owner->ownerOutput(); } } /***********************************/ /* main.cpp */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <iostream> #include <cstdlib> #include "testclass.h" using namespace std; int main(int argc, char *argv[]) { TestClass tc; tc.output(); return EXIT_SUCCESS; } I don't mean to offend anybody by posing lyrics here, but these seemed apropos to the subject at hand. Watching Me Watching You -- Jethro Tull I sit by the cutting on the Beaconsfield line He's watching me watching the trains go by And they move so fast - Boy, they really fly He's still watching me watching you watching the trains go by And the way he stares - feel like locking my door And pulling my phone from the wall His eyes, like lights from a laser, burn Making my hair stand - making the goose-bumps crawl He's watching me watching you watching him watching me I'm watching you watching him watching me watching Stares At the cocktail party with a Bucks fizz in my hand I feel him watching me watching the girls go by And they move so smooth without even trying He's still watching me watching you watching the trains go by And the crowd thins and he moves up close but he doesn't speak I have to look the other way But curiosity gets the better part of me and I peek Got two drinks in his hand - see his lips move - What the Hell's he trying to say.

On Tue, 8 Apr 2003 05:47:00 -0400 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
The reason I asked the question is that I'm not sure that every instance of a class will have the same size. If they don't, then how would the result of incrementing a pointer (ptr++ ) be calculated? You can count on it being consistent. *ptr will fetch the instance of the class that ptr points to. *(ptr + 1) will fetch the next instance of that class, assuming you allocated them as an array. so:
MyClass *ptr = new MyClass[2]; ptr points to the first instance, and ptr + 1 points to the next. BUT, if you do: MyClass *ptr = new MyClass; MyClass *ptr1 = new MyClass; You cannot safely predict location of the next instance. In most instances, ptr1 will not be (ptr + 1). The run time library may allocate the space for ptr1 anywhere. While we talk about the heap, which is the classic place where dynamic memory is allocated, newer technology today may use mmap to allocate dynamic objects. Historically, Unix and Linux used the brk and sbrk system calls which allocate virtual memory contiguously above the program's data segment. But, even on the heap, malloc() (which is usually the underlying memory allocator for new), may reclaim some freed memory for ptr but not for ptr1 so they will not be contigious. So, you can only count on pointer arithmetic working properly for object allocated contiguously. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

On 8 Apr 2003 at 5:47, Steven T. Hatton wrote: From: "Steven T. Hatton" <hattons@globalsymmetry.com> Organization: Global Symmetry To: suse-programming-e@suse.com Date sent: Tue, 8 Apr 2003 05:47:00 -0400 Subject: Re: [suse-programming-e] Pointer strangeness [snip...]
The reason I asked the question is that I'm not sure that every instance of a class will have the same size. If they don't, then how would the result of incrementing a pointer (ptr++ ) be calculated?
Each instance of a class -is- the same size, and the compiler handles the low level details of how to increment a pointer, unless you have a pointer to a void, in which case the increment op doesn't work. If you try to put data into your class definition which does not have a fixed size, the compiler will turn nasty and refuse to compile it :) As far as your other question goes, a class constructor is called in two cases: 1. When a variable of the class type is declared - ie: MyClass my_class1; // calls constructor with no parameters MyClass my_class2(params); // calls constructor with parameters 2. When a object of the class type is created with new - ie: MyClass *my_class_ptr1 = new MyClass; MyClass *my_class_ptr2 = new MyClass(params); The classes destructor is called in the following circumstances: 1. When a variable of the class type goes out of scope - which usually means at the end of the block in which it was declared. For most automatic variables that would be when the function exits, but you could, for instance, declare a variable inside a loop, and that would go out of scope when the loop exits. For static variables this is when the program exits. Note that static variable are created before the program enters main(). You have no control over the order in which statics are constructed and destroyed, except that the standard guarantees that they will be destroyed in the reverse order to which they were constructed! 2. When objects are destroyed using delete. Note that if you created an array of objects eg: MyClass *my_class_ptr = new MyClass[MAX_MYCLASS]; then you must destroy the array with delete [] eg: delete [] my_class_ptr; The purpose of constructors is so that you can write initialisation code for your classes and be sure that it will automatically be called when you create an object of that class. Destructors perform guaranteed clean up when you destroy an object. [lotsa stuff snipped here...] Hope this helps alan -- http://www.ibgames.net/alan Registered Linux user #6822 http://counter.li.org Winding Down - Weekly Tech Newsletter - subscribe at http://www.ibgames.net/alan/winding/mailing.html

On Mon, 7 Apr 2003 00:08:54 -0500 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
Yes, my statement doesn't really make a lot of sense now that I think about it. What matters is not how the class is defined, but rather how objects of that type are instantiated. A class definition is saved in the compiler's memory space during compilation. Non-inline functions certainly do take up space in your program's text segment (usually). class static variables are generally allocated in the program's data segment. But the rest of the class is simply a template for the compiler to use when the class is instatiated.
As Anders mentioned, there are a lot of implementaiton details. How the compiler actually allocates the storage for the class once instatiated is up to the compiler. In general, automatic variables (eg. those vatiables that exist inside of a function) are allocated on the stack. But, the compiler may actualy allocate them elsewhere so they BEHAVE as if they were allocated on the stack. When you use the new operator, the data you allocate BEHAVES like it was allocated on the heap, but some Unix compilers are using MMAP. I don't specifically know what gcc 3.0 actually does in this case.
I'm still fumbling about with some of these notions. The /new/ operator returns a pointer to an object of the class upon which it was called. If I simply declare a variable of that type, it seems to be created, and the default constructor seems to be called to initialize its members. But it would seem this is not synonymous with an implicit invocation of new. For one thing, the object is accessible through a variable name rather than a pointer reference.
Now if I do something like
void doThis() { MyClass mc; mc.myMethod(); }
I implicitly create an instance of MyClass and set the variable mc to hold that object. If, in turn, MyClass has a member variable of some object type, that is created in a similar manner. I assume this member object is destroyed when its owner is destroyed. Correct? In this case. mc is allocated as a local variable. The compiler may allocate some components of the class on the heap, or it may mmap them. But, they will behave as if they were local variables. When you return from doThis(), the storage for mc will be returned back to the system. void doThis() { MyClass *mc = new MyClass; mc->myMethod(); } In this case, the storage for mc will be allocated in a persistent mannter, classically on the heap, but the compiler may mmap it. When you return from doThis, the variable mc (eg. the pointer) goes out of scope, and you have a memory leak.
One ofthe important things to remember, is that variables within the class must be explicitly initialized, either from within the constructors (by default or explicitly), or explicitly by you. example: string foo("a string"); // the string, foo is explicitly initialized // by you through the constuctor. string *foo = new string("a string"); // same as above. string foo; // The default initialization will create the default // empty string for the string class. When you design a class, you should make sure that all the variables in the class are initialized when the constructor is called. Otherwise, you could have some difficulties later. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

On Monday 07 April 2003 11:09 am, Jerry Feldman wrote:
On Mon, 7 Apr 2003 00:08:54 -0500
"Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
Yes, my statement doesn't really make a lot of sense now that I think about it. What matters is not how the class is defined, but rather how objects of that type are instantiated.
A class definition is saved in the compiler's memory space during compilation. Non-inline functions certainly do take up space in your program's text segment (usually). class static variables are generally allocated in the program's data segment. But the rest of the class is simply a template for the compiler to use when the class is instatiated.
Did you really mean 'compiler' here? I'm way out in unfamiliar territory here, but I would guess it is the OS kernel which uses this 'template' for instantiation. I'm trying to recall if the actual instructions of a function get placed on the stack. My guess is, instructions *do* get placed on the stack along with local variables.
As Anders mentioned, there are a lot of implementaiton details. How the compiler actually allocates the storage for the class once instatiated is up to the compiler. In general, automatic variables (eg. those vatiables that exist inside of a function) are allocated on the stack.
I can tell I need to really hit the books if I want to understand this stuff. As I recall from years ago, the compiler does have a lot to do with the runtime behavior of the program. Nonetheless, the compiler has already done its job, and the kernel is the component actually doing the instantiation of classes as objects, and the memory allocation. I'm sure you know this, and are simply using a manner of speaking which implies as much. I'm just pointing out that there is yet more involved than the compiler.
In this case. mc is allocated as a local variable. The compiler may allocate some components of the class on the heap, or it may mmap them. But, they will behave as if they were local variables. When you return from doThis(), the storage for mc will be returned back to the system. void doThis() { MyClass *mc = new MyClass; mc->myMethod(); } In this case, the storage for mc will be allocated in a persistent mannter, classically on the heap, but the compiler may mmap it. When you return from doThis, the variable mc (eg. the pointer) goes out of scope, and you have a memory leak.
Yes. This is the part that really matters to a novice like me.
One of the important things to remember, is that variables within the class must be explicitly initialized, either from within the constructors (by default or explicitly), or explicitly by you.
example: string foo("a string"); // the string, foo is explicitly initialized // by you through the constuctor. string *foo = new string("a string"); // same as above. string foo; // The default initialization will create the default // empty string for the string class.
When you design a class, you should make sure that all the variables in the class are initialized when the constructor is called. Otherwise, you could have some difficulties later.
However, from my observations, if I simply declare a variable of derived type, and never explicitly initialize that variable, the constructor of that class *is* invoked, and the member variables of that object *are* initialized. I'm trying to put together an example complex enough to demonstrate some of the issues which had me confused, and yet simple enough to present on this list. Part of that example involves the chaining of constructors. That is, the instantiation of objects within the constructor. This happens when I am writing GUI code. I want the main window to have 'children' which in turn may have children. I found I could do this if the children were referenced by pointers from the parent object, but not if the children were members of the parent objects. By looking over the QT example code, the Trolls typically use pointers in such cases. STH

A class definition is saved in the compiler's memory space during compilation. Non-inline functions certainly do take up space in your program's text segment (usually). class static variables are generally allocated in the program's data segment. But the rest of the class is simply a template for the compiler to use when the class is instatiated.
Did you really mean 'compiler' here? I'm way out in unfamiliar territory here, but I would guess it is the OS kernel which uses this 'template' for instantiation. I'm trying to recall if the actual instructions of a function get placed on the stack. My guess is, instructions *do* get placed on the stack along with local variables.
I thought I'd stick my nose back into this thread. If I've missed too much to say anything useful which hasn't been said before, just ignore me. :o) Yes, he means compiler. Remember, the purpose of a compiler is to put together a set of assembly language instructions, and make them into an executable which the OS can run. At *compile time* the compiler will look at your class definition and say "that requires <n> bytes to store one object". It will also look at the class' methods and say "this is the code which that class definition needs available". It will therefore squirrel away one copy of all the method code. Your guess in the quote above is wrong. :o) The instructions which make up a function are stored once in the text segment. No need to make hundreds of copies of a bit of code just 'cos you've got hundreds of objects instantiated. They can share! When the compiler finds a bit of code which instantiates an object, either on the stack: MyClass fred; or on the heap: MyClass* fred = new MyClass; it needs to generate some code to do it. Remember: the compiler isn't doing the actual instantiation; the compiler is generating the code which does it when the OS runs the resultant program. So the psuedo-code generated will be: allocate <n> bytes in the right place (i.e. on the stack or the heap) call constructor subroutine with that memory block as a parameter When the OS runs the program, a call to the system's memory allocation routine (malloc or similar under Linux) will be made. That will be followed by a call to the place in the program text segment where the constructor code has been placed, basically saying "here's an empty block of memory big enough to hold the object - fill it in!".
the runtime behavior of the program. Nonetheless, the compiler has already done its job, and the kernel is the component actually doing the instantiation of classes as objects, and the memory allocation.
Not quite. The program which the compiler has generated, and which is running, instantiates the objects. The program may very well use kernel or glibc facilities to do this (because the compiler knows about those facilities and generated code to use them), but that doesn't mean it's the kernel doing the instantiation.
However, from my observations, if I simply declare a variable of derived type, and never explicitly initialize that variable, the constructor of that class *is* invoked, and the member variables of that object *are* initialized.
You mean, if you say: MyClass fred; then the constructor for MyClass is called? Yes. And the member variables will be set to 0s by default (see C++ spec), or anything that MyClass' constructor, or any of the parent class' constructors sets them to explicitly.
By looking over the QT example code, the Trolls typically use pointers in such cases.
Yes, because QT is about widgets and widgets need to remain in place after the code which creates them has been and gone. (e.g. Can't have all those buttons which your toolbar created disappearing when the toolbar constructor is completed and exits, can you?) So Qt creates the buttons on the heap: QButton* button1 = new QButton( "Quit" ); and keeps the pointer (button1 in this case) around in the Toolbar class. When the toolbar is destroyed, the destructor will ensure all the objects the button pointers are pointing to are correctly destroyed. If Qt did it on the stack: QButton button1("Quit"); when the toolbar constructor exits, the stack memory allocated for that button will be reclaimed and reused. That would be *bad*! Qt, BTW, does all this pointer juggling for you: you create a toolbar and add buttons to it. When you destroy your toolbar, Qt handles the tidying up of all the buttons, etc. Gotta love Qt... :o) -- "...our desktop is falling behind stability-wise and feature wise to KDE ...when I went to Mexico in December to the facility where we launched gnome, they had all switched to KDE3." - Miguel de Icaza, March 2003

On Tuesday 08 April 2003 05:13 am, Derek Fountain wrote:
Did you really mean 'compiler' here? I'm way out in unfamiliar territory here, but I would guess it is the OS kernel which uses this 'template' for instantiation. I'm trying to recall if the actual instructions of a function get placed on the stack. My guess is, instructions *do* get placed on the stack along with local variables.
I thought I'd stick my nose back into this thread. If I've missed too much to say anything useful which hasn't been said before, just ignore me. :o)
I may have missed more than you, and I've read it all! ;-)
Yes, he means compiler. Remember, the purpose of a compiler is to put together a set of assembly language instructions, and make them into an executable which the OS can run.
This is an interesting topic, which I hope not to go to deep into presently. What you said about assembly code is the way they taught it to me in my lower level courses. But, IIRC, one of my professors (the Italian guy who always held his coke as if it were a cocktail glass, and his chalk as if it were a cigarette) told us that RISC compilers will likely forego the assembly language step and directly produce binary instructions. The part that I'm not completely sure of is the role of glibc, and etc. For the sake of the original discussion, however, none of this matters. I'm not ready to go marching into this field quite yet.
At *compile time* the compiler will look at your class definition and say "that requires <n> bytes to store one object".
I have some uncertainty here. What you say makes sense, and I really believe this is what happens. However, what about objects such as strings? The compiler cannot know a priori what data will be stored in a string. This suggest to me the data of a string is not 'part' of the object. It is data pointed to by a member of the object.
It will also look at the class' methods and say "this is the code which that class definition needs available". It will therefore squirrel away one copy of all the method code. Your guess in the quote above is wrong. :o) The instructions which make up a function are stored once in the text segment. No need to make hundreds of copies of a bit of code just 'cos you've got hundreds of objects instantiated. They can share!
Again, my recollection of how the stack works is a bit hazy. What you say makes sense for objects on the heap, but at some point, the instructions need to be placed in the CPU. Either the image of a function invocation goes on the stack as a whole, or it consists of an entry address into the shared program image, and a return address to be loaded in the instruction pointer register when the function completes. Typically we wouldn't have hundreds of images of a function on the stack. Such a situation would only occur in some kind of recursive invocation where a function calls itself and therefore causes another instance of itself to be loaded on the stack. [I'm gonna back off form these implementation details for now.]
However, from my observations, if I simply declare a variable of derived type, and never explicitly initialize that variable, the constructor of that class *is* invoked, and the member variables of that object *are* initialized.
You mean, if you say:
MyClass fred;
then the constructor for MyClass is called? Yes. And the member variables will be set to 0s by default (see C++ spec), or anything that MyClass' constructor, or any of the parent class' constructors sets them to explicitly.
Take a look at the code I posted in my previous message. That isn't what seems to be happening.
By looking over the QT example code, the Trolls typically use pointers in such cases.
Yes, because QT is about widgets and widgets need to remain in place after the code which creates them has been and gone. (e.g. Can't have all those buttons which your toolbar created disappearing when the toolbar constructor is completed and exits, can you?) So Qt creates the buttons on the heap:
QButton* button1 = new QButton( "Quit" );
There's something I'm not getting here. button1 is a variable being assigned in the constructor. It is not destroyed when the constructor returns. Why should QButton button1 = someKindOfMagicToMakeAButton(); be destroyed upon returning from the constructor?
Qt, BTW, does all this pointer juggling for you: you create a toolbar and add buttons to it. When you destroy your toolbar, Qt handles the tidying up of all the buttons, etc. Gotta love Qt... :o)
QT seems very powerful, and well designed. I didn't realize how much C++ I didn't know when I started. May people wouldn't spend as much time trying to get at what's actually going on 'under the hood'. Some of this may never help me write code. I suspect, however, many of the people who simply pick up QT and start using the designer will reach a point where everything falls appart, and they don't know what to do to fix it. STH

On Tuesday 08 April 2003 12:45, Steven T. Hatton wrote:
But, IIRC, one of my professors (the Italian guy who always held his coke as if it were a cocktail glass, and his chalk as if it were a cigarette) told us that RISC compilers will likely forego the assembly language step and directly produce binary instructions.
Discounting macro assemblers, there is a one-to-one correspondence between assembly instructions and binary instructions. The former is just a human readable version of the latter.
Again, my recollection of how the stack works is a bit hazy. What you say makes sense for objects on the heap, but at some point, the instructions need to be placed in the CPU. Either the image of a function invocation goes on the stack as a whole, or it consists of an entry address into the shared program image, and a return address to be loaded in the instruction pointer register when the function completes. Typically we wouldn't have hundreds of images of a function on the stack. Such a situation would only occur in some kind of recursive invocation where a function calls itself and therefore causes another instance of itself to be loaded on the stack.
As far as I know, there are only two times when there is executable code on the stack. One is when you've been cracked. and the cracker uses a buffer overflow to insert the code, and the other is something called trampolines. which you can read about here http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html Generally speaking, the areas of memory used to store data don't store executable code. On some hardware platforms that can be enforced. On the sparc, for example, you can tag a memory area as 'data', and it will trigger an error if the program then tries to go there in its execution.
QButton* button1 = new QButton( "Quit" );
There's something I'm not getting here. button1 is a variable being assigned in the constructor. It is not destroyed when the constructor returns. Why should
The variable button1 is destroyed when the constructor exits. The object it refers to is not. Normally in QT, you use the variables like button1 to set other variables, using methods like setMainWidget(). Those methods assign the objects to internal variables in the containers, so when the temporary variable button1 dies (when the constructor exits), they're not forgotten. Anders

On Tuesday 08 April 2003 07:46 am, Anders Johansson wrote:
On Tuesday 08 April 2003 12:45, Steven T. Hatton wrote:
But, IIRC, one of my professors (the Italian guy who always held his coke as if it were a cocktail glass, and his chalk as if it were a cigarette) told us that RISC compilers will likely forego the assembly language step and directly produce binary instructions.
Discounting macro assemblers, there is a one-to-one correspondence between assembly instructions and binary instructions. The former is just a human readable version of the latter.
I don't recall the details of the lecture, but I do recall that in the example he used, there was not a one-to-one correspondence between assembly code, and the compiled binary executable.
Again, my recollection of how the stack works is a bit hazy. What you say makes sense for objects on the heap, but at some point, the instructions need to be placed in the CPU. Either the image of a function invocation goes on the stack as a whole, or it consists of an entry address into the shared program image, and a return address to be loaded in the instruction pointer register when the function completes. Typically we wouldn't have hundreds of images of a function on the stack. Such a situation would only occur in some kind of recursive invocation where a function calls itself and therefore causes another instance of itself to be loaded on the stack.
As far as I know, there are only two times when there is executable code on the stack.
I looked over the examples in Sebesta's book, and I will agree that I guessed wrong. I'm not srue what Mathematica and Lisp do, but these are birds of a different feather, AFAIK.
One is when you've been cracked. and the cracker uses a buffer overflow to insert the code, and the other is something called trampolines. which you can read about here
Thanks, I'll skip that for now. I'm already confused enought. :-)
QButton* button1 = new QButton( "Quit" );
There's something I'm not getting here. button1 is a variable being assigned in the constructor. It is not destroyed when the constructor returns. Why should
The variable button1 is destroyed when the constructor exits. The object it refers to is not.
Normally in QT, you use the variables like button1 to set other variables, using methods like setMainWidget(). Those methods assign the objects to internal variables in the containers, so when the temporary variable button1 dies (when the constructor exits), they're not forgotten.
I should have stated that better. What I meant to say was: class MyClass { public: MyClass::MyClass(); ~MyClass() private: SomeClass mySomeClass; int myInt; }; MyClass::MyClass() { this->mySomeClass = someKindOfMagicToInstantiate(SomeClass); } It seems that I could pass an object of type SomeClass, and use that to initialize mySomeClass in the constructor. But that is a bit different.
Anders
STH

On Tue, 8 Apr 2003 08:55:57 -0400 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
I don't recall the details of the lecture, but I do recall that in the example he used, there was not a one-to-one correspondence between assembly code, and the compiled binary executable. Since I cowrote the assembler no used on Tru64 Unix, I guess I can comment on this. Most modern assemblers have macros. But even those that are not macro assemblers, there are things that may not be entirely primitive. For instance (for the Alpha processor): stq $16, foo Store quad stored in integer register 16 to location foo. This will generate the code to convert foo to an address stored in a register. I havn't worked with Intel assemblers in a few years, so I cannot comment intelligently on that.
-- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

At *compile time* the compiler will look at your class definition and say "that requires <n> bytes to store one object".
I have some uncertainty here. What you say makes sense, and I really believe this is what happens. However, what about objects such as strings? The compiler cannot know a priori what data will be stored in a string. This suggest to me the data of a string is not 'part' of the object. It is data pointed to by a member of the object.
Spot on. The object will keep track of the memory it allocates, and will tidy up after itself when it's destroyed.
pointer register when the function completes. Typically we wouldn't have hundreds of images of a function on the stack. Such a situation would only occur in some kind of recursive invocation where a function calls itself and therefore causes another instance of itself to be loaded on the stack.
A method call isn't a particularly clever thing. There's a bit of code somewhere in the program text segment which gets called just like any other function. The only difference between it and a bog standard C function is that the compiler generates it's code such that it takes one extra parameter on top of the ones the programmer writes: a pointer to the object it has to work with. This is the 'this' pointer which you can use (implicitly or explicitly) inside the code. Put another way, the compiler ensures that when it sees something like: ObjClass* myObj; myObj->aMethod( x, y, z ); it actually generates code for the call like: ObjClass::aMethod( myObj, x, y, z ); and the method definition is like: ObjClass::aMethod( ObjClass* this, int x, int y, int z ) { ... }
[I'm gonna back off form these implementation details for now.]
Oh. OK. Ignore the bit above!
never help me write code. I suspect, however, many of the people who simply pick up QT and start using the designer will reach a point where everything falls appart, and they don't know what to do to fix it.
Certainly no harm in understanding what's going on! Designer, though, isn't an IDE. It's just a GUI code generator which never takes any real control out of your hands. I guess there are environments where your point is valid though - I don't use them. -- "...our desktop is falling behind stability-wise and feature wise to KDE ...when I went to Mexico in December to the facility where we launched gnome, they had all switched to KDE3." - Miguel de Icaza, March 2003

On Tue, 8 Apr 2003 04:14:13 -0400 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
I can tell I need to really hit the books if I want to understand this stuff. As I recall from years ago, the compiler does have a lot to do with the runtime behavior of the program. Nonetheless, the compiler has already done its job, and the kernel is the component actually doing the instantiation of classes as objects, and the memory allocation. I'm sure you know this, and are simply using a manner of speaking which implies as much. I'm just pointing out that there is yet more involved than the compiler.
I think Derek covered most of your points appropriately. As I mentioned earlier, I think you should get a good book on C++, and proceed through the example code. Several good C++ books were listed by me and others last month. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

On Mon, 31 Mar 2003 10:08:33 -0500 (EST) "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
Ok, now I see what's going on. My pointing to temp with memberIntPtr doesn't place a 'handle' on so when temp is gone, that memory is up for grabs As I said, tmp is allocated on the stack. When the function returns, the stack is unwound and then used by another function. char *s = "abcd" + 2; For your own edification, try explaining this. This a perfectly legal thing to do. A friend used to ask this as an interview question.
-- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9

On Monday 31 March 2003 12:38 pm, Jerry Feldman wrote:
On Mon, 31 Mar 2003 10:08:33 -0500 (EST)
"Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
Ok, now I see what's going on. My pointing to temp with memberIntPtr doesn't place a 'handle' on so when temp is gone, that memory is up for grabs
As I said, tmp is allocated on the stack. When the function returns, the stack is unwound and then used by another function. char *s = "abcd" + 2; For your own edification, try explaining this. This a perfectly legal thing to do. A friend used to ask this as an interview question.
-- Jerry Feldman <gaf@blu.org>
*s=='c'?
participants (8)
-
alan@ibgames.com
-
Anders Johansson
-
Derek Fountain
-
expatriate
-
Jerry Feldman
-
Jerry Feldman
-
John Lamb
-
Steven T. Hatton