new operator and memory allocation

L

Lionel

Hi all,

Just wondering exactly how memory is allocated using the new operator?
More specifically I am interested in how the memory is calculated for
globable variables? I recently stumbled into a problem which corrected
my way of thinking.

Now, people probably won't be able to answer much to that question, so I
will give an example. This is example uses the qt library qstring.h, but
I assume this would be similar to the C++ string.h and don't think this
should be OT.

e.g. I have a class header:

class AClass {
public:
AClass( QString id );
private:
QString identifier;
int aInt;
};

And implementation:
AClass::AClass( QString id ) {
identifier = id;
aInt = 0;
}

Now, I thought the memory would be allocated on the stack for identifier
and aInt, however it appears that QString isn't a type, and so aInt gets
memory but there is no guarantee for identifier. This means the memory
address of identifer can potentially get used elsewhere if the function
where identifier was created returns. Not a desirable effect.

So as it turns out I use the * and new operator and it quite obviously
is fine.

So, how does C++ handle allocation in such situations?

Thanks and sorry for the length of the post. Hopefully this is
understandable.

Lionel.
 
A

Artie Gold

Lionel said:
Hi all,

Just wondering exactly how memory is allocated using the new operator?
More specifically I am interested in how the memory is calculated for
globable variables? I recently stumbled into a problem which corrected
my way of thinking.

Now, people probably won't be able to answer much to that question, so I
will give an example. This is example uses the qt library qstring.h, but
I assume this would be similar to the C++ string.h and don't think this
should be OT.

Well, the particulars *are* OT, but the general concepts behind the
problem you're seeing are not, so I'll continue:

e.g. I have a class header:

class AClass {
public:
AClass( QString id );
private:
QString identifier;
int aInt;
};

And implementation:
AClass::AClass( QString id ) {
identifier = id;
aInt = 0;
}

BTW, write this using initializer lists:

AClass::AClass(QString id) : identifier(id), aInt(0) {}
Now, I thought the memory would be allocated on the stack for identifier
and aInt, however it appears that QString isn't a type, and so aInt gets

If QString *isn't* a type, there would be no chance of this compiling.
memory but there is no guarantee for identifier. This means the memory
address of identifer can potentially get used elsewhere if the function
where identifier was created returns. Not a desirable effect.

So as it turns out I use the * and new operator and it quite obviously
is fine.

So, how does C++ handle allocation in such situations?

Have you looked at the <qstring.h> header? Apparently the only data
members it contains are two pointers to underlying objects (assumedly
there is memory allocated to them in the QString constructors).

What's probably happening is that you're geting a shallow copy of `id'
in your constructor, and when `id' goes out of scope, it's taking its
underlying data members with it.

You really need to know How Things Work before working with this kind of
stuff.

HTH,
--ag
 
L

Lionel

Artie said:
Well, the particulars *are* OT, but the general concepts behind the
problem you're seeing are not, so I'll continue:

First of all, in C++, it's <string> and, like qstring.h, it's a *header*
not a library. This is a fundamental distinction you need to understand.

Understood :). For some reason I often have compilation problems when I
just go #include <string>. I know I should figure out why as #include
BTW, write this using initializer lists:

AClass::AClass(QString id) : identifier(id), aInt(0) {}

I'm stuck in a Java way of programming, which in this instance I still
prefer for readability. I have read that the above method can be more
efficient, but seriously how much difference does it make?
If QString *isn't* a type, there would be no chance of this compiling.



Have you looked at the <qstring.h> header? Apparently the only data
members it contains are two pointers to underlying objects (assumedly
there is memory allocated to them in the QString constructors).

What's probably happening is that you're geting a shallow copy of `id'
in your constructor, and when `id' goes out of scope, it's taking its
underlying data members with it.

You really need to know How Things Work before working with this kind of
stuff.

I understand what you are saying and it is as I thought. C++ works
slightly differently than what I was expecting. I was hoping that
declaring a global variable would allocate the memory in the scope that
class, then passing in the parameter id as above, would pass by value.
This clearly isn't the case.

Thanks for the reply.

Lionel.
 
A

Artie Gold

Lionel said:
Artie Gold wrote:
[snip]

Understood :). For some reason I often have compilation problems when I
just go #include <string>. I know I should figure out why as #include
<string.h> is deprecated . . . it may be qt related in this case, I'm
not sure.

<string.h> is a C header for manipulation of C-style `strings', i.e.
null-terminated sequences of chars. said:
I'm stuck in a Java way of programming, which in this instance I still
prefer for readability. I have read that the above method can be more
efficient, but seriously how much difference does it make?
The difference is that initialization is initialization and assignment
is assignment. In most cases, there will be very little run time
difference between the two -- but `saying what you mean' is usually good
advice for programming.

Mentioning Java as you do, remember that in Java, (almost) everything is
really a pointer; (almost) nothing is allocated on `the stack'. In C++,
there's a definite distinction between the two, which has further
implications (particularly as regards polymorphism).
I understand what you are saying and it is as I thought. C++ works
slightly differently than what I was expecting. I was hoping that
declaring a global variable would allocate the memory in the scope that
class, then passing in the parameter id as above, would pass by value.
This clearly isn't the case.

Well, it *does* pass by value. It's just that the value passed really
only contains two pointers that point somewhere else.

The other thing to note is the difference between a language where free
store allocation/deallocation is manual as opposed to a garbage
collected language; in the former not only can things be changed behind
your back (the shallow copy problem, with which I'm sure you're
familiar) but they can *disappear entirely*.

I would recommend going to http://www.accu.org and finding a book about
C++ appropriate for your background and learning style.
Thanks for the reply.
You're welcome.

HTH,
--ag
 
S

Stephen M. Webb

Lionel said:
Just wondering exactly how memory is allocated using the new operator?
More specifically I am interested in how the memory is calculated for
globable variables? I recently stumbled into a problem which corrected
my way of thinking.

Now, people probably won't be able to answer much to that question, so I
will give an example. This is example uses the qt library qstring.h, but
I assume this would be similar to the C++ string.h and don't think this
should be OT.

e.g. I have a class header:

class AClass {
public:
AClass( QString id );
private:
QString identifier;
int aInt;
};

And implementation:
AClass::AClass( QString id ) {
identifier = id;
aInt = 0;
}

Now, I thought the memory would be allocated on the stack for identifier
and aInt, however it appears that QString isn't a type, and so aInt gets
memory but there is no guarantee for identifier. This means the memory
address of identifer can potentially get used elsewhere if the function
where identifier was created returns. Not a desirable effect.

So as it turns out I use the * and new operator and it quite obviously
is fine.

(1) Your example has nothing to do with the new operator. Can you
provide an example that might be relevant to te question you're trying
to ask?

(2) Objects will be constructed for both the "identifier" and the
"aInt" members of any AClass objects you create. Other than not being
compileable because you did not include the appropriate headers, the
above code is correct. Please make sure you post compileable code in
the future.

(3) Getting into OT details, std::string and QString differ in the
fact that a std::string object is always fully-constructed, but a
QString object can be partially constructed (that is, a comparison
with QString::null will return true). Attempting operations on a
constructed-but-not-initialized QString object will bring you grief.
Perhaps this is the source of confusion that has lead to your
question?

(4) You didn't show how you used the new operator to solve your
(unspecified) problem, but I suspect it may not be fine if you don't
use delete to destroy the object at the appropriate time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top