memory size allocated by new

M

mast2as

This question has been posted to this forum before and I read the
thread but found that the answers were perhaps imcomplete, so I am
trying again.

Whenever I am creating objects I would like to keep track of the
memory which is used for each object (for stats purpose). They are 2
basic approaches, one is to write a Memory manager type of class where
new & delete would be overloading the standard new & delete operator.
Each time the new member function of this class would be called I
could update a variable to would keep track of the bytes allocated by
new. This not completly satisafactory for me as this would be global
to the application.

Another way is to just recompute the size of the byte arrays and add
the result to a member variable. Something like that...

class A
{
private:
int *data;
float *floatData;
size_t mem;
public:
A( size_t arraySize, size_t arraySize2 )
{
mem = 0;
data = new int[ arraySize ];
dataFloat = new float[ arraySize2 ]
mem += sizeof( int ) * arraySize;
mem += sizeof( float ) * arraySize2;
}
}

I have read that 'new' reserves the memory which is needed for the
array of a certain type, plus some additional info at the beginning at
this array (which delete uses to know what is the size of the array it
needs to free). So instead of recompute the size of the array in bytes
and summing up the result to the variable mem is there a way one could
access the size of an array in bytes used by an array or created by
new ?

thanks -
 
A

adrian.hawryluk

This question has been posted to this forum before and I read the
thread but found that the answers were perhaps imcomplete, so I am
trying again.

Whenever I am creating objects I would like to keep track of the
memory which is used for each object (for stats purpose). They are 2
basic approaches, one is to write a Memory manager type of class where
new & delete would be overloading the standard new & delete operator.
Each time the new member function of this class would be called I
could update a variable to would keep track of the bytes allocated by
new. This not completly satisafactory for me as this would be global
to the application.

Sorry, I'm not understanding you. Are you asking for some way of
tracking how many bytes are being allocated globally? Or only in
certain spots?
Another way is to just recompute the size of the byte arrays and add
the result to a member variable. Something like that...

class A
{
private:
int *data;
float *floatData;
size_t mem;
public:
A( size_t arraySize, size_t arraySize2 )
{
mem = 0;
data = new int[ arraySize ];
dataFloat = new float[ arraySize2 ]
mem += sizeof( int ) * arraySize;
mem += sizeof( float ) * arraySize2;
}

}

I'm not getting this either. You are allocating arrays, and trying to
store the size of the arrays, but you only want it done in a class?
I have read that 'new' reserves the memory which is needed for the
array of a certain type, plus some additional info at the beginning at
this array (which delete uses to know what is the size of the array it
needs to free). So instead of recompute the size of the array in bytes
and summing up the result to the variable mem is there a way one could
access the size of an array in bytes used by an array or created by
new ?

Ok, this I get. An array will be sizeof(type)*numberOfElements but if
the type has a destructor, then you will have to add sizeof(size_t) to
it.

If you just want to know how many bytes are being allocated globally,
do this:

<sourceFile>
static size_t bytesAllocatedSoFar = 0;

void* ::eek:perator new(size_t size)
{
bytesAllocatedSoFar += size;
return malloc(size);
}

void* ::eek:perator new[](size_t size)
{
bytesAllocatedSoFar += size;
return malloc(size);
}

void ::eek:perator delete(void *memory)
{
return free(memory);
}

void ::eek:perator delete[](void *memory)
{
return free(memory);
}
</sourceFile>

But if any part of your programme uses malloc, this information is
lost.

If you want to access bytesAllocatedSoFar you will either define it
extern in the header file (and remove static from the source file), or
create an access function prototype in the header file and define it
in the source as returning bytesAllocatedSoFar.

Hope this helps.


Adrian
 
R

Ron Natalie

This question has been posted to this forum before and I read the
thread but found that the answers were perhaps imcomplete, so I am
trying again.

Whenever I am creating objects I would like to keep track of the
memory which is used for each object (for stats purpose). They are 2
basic approaches, one is to write a Memory manager type of class where
new & delete would be overloading the standard new & delete operator.
Each time the new member function of this class would be called I
could update a variable to would keep track of the bytes allocated by
new. This not completly satisafactory for me as this would be global
to the application.

Another way is to just recompute the size of the byte arrays and add
the result to a member variable. Something like that...

class A
{
private:
int *data;
float *floatData;
size_t mem;
public:
A( size_t arraySize, size_t arraySize2 )
{
mem = 0;
data = new int[ arraySize ];
dataFloat = new float[ arraySize2 ]
mem += sizeof( int ) * arraySize;
mem += sizeof( float ) * arraySize2;
}
}

I have read that 'new' reserves the memory which is needed for the
array of a certain type, plus some additional info at the beginning at
this array (which delete uses to know what is the size of the array it
needs to free). So instead of recompute the size of the array in bytes
and summing up the result to the variable mem is there a way one could
access the size of an array in bytes used by an array or created by
new ?

thanks -


Your class is defective and sloppy. I'd write it like this:

class A {
private:
std::vector<int> data;
std::vector<float> floatData;
public:
A(size_t arraySize, size_t arraySize2) :
data(arraySize), floatData(arraySize2) { }
size_t approximate_size() {
return data.size() * sizeof(int) +
floatData.size() * sizeof(float);
}
};

By using vector, you class automatically becomes well defined in copy
and assignment. Further it frees you from having to worry about
memory allocation. You can easily change the size as well.

The approximate_size function returns the smae thing your "mem"
variable would have, but only needs be calculated when used (and
is correct in light of resizing of the vectors).
 
M

mast2as

Sorry, I'm not understanding you. Are you asking for some way of
tracking how many bytes are being allocated globally? Or only in
certain spots?

Sorry Adrian I wasn't clear. I am only interested in the memory used
by objects of class A. So for example if they are 100 objects of class
A which are created all with different sizes for floatData & data, I
want to know how memory is used by these 100 objects. This is why I
wanted to avoid using some sort of memory manager class that would
have new and delete overloaded.

My question was also about these extra bits that the new operator
seems to control to save info about the size of the byte arrays it has
created. I was wondering if that info could be accessed somehow, so
one could get that value from there !
 
R

Ron Natalie

Ok, this I get. An array will be sizeof(type)*numberOfElements but if
the type has a destructor, then you will have to add sizeof(size_t) to
it.

That's something reserved to the implementation. All the standard says
is the size passed to the operator new for arrays is some fixed
(possibly zero) size PLUS the number of elements * sizeof the element.
 
A

adrian.hawryluk

That's something reserved to the implementation. All the standard says
is the size passed to the operator new for arrays is some fixed
(possibly zero) size PLUS the number of elements * sizeof the element.

True. What I state is the minimum. There could be other data that I
have not accounted for.


Adrian
 
A

adrian.hawryluk

Sorry Adrian I wasn't clear. I am only interested in the memory used
by objects of class A. So for example if they are 100 objects of class
A which are created all with different sizes for floatData & data, I
want to know how memory is used by these 100 objects. This is why I
wanted to avoid using some sort of memory manager class that would
have new and delete overloaded.

My question was also about these extra bits that the new operator
seems to control to save info about the size of the byte arrays it has
created. I was wondering if that info could be accessed somehow, so
one could get that value from there !

First off, the new operator does not 'control' the number of bytes it
allocates, unless by control, you mean add to beyond what the compiler
is going to add to it. I.e. I stated that there could be a size_t
value at the begining of an array, this is done by the compiler, not
the new operator. The new operator is passed the size the compiler
needs to do its thing, and as stated by Ron, it is implementation
dependent. However, the new operator can add extra stuff if it wants,
as long as the returned pointer points to the space that the compiler
can use.

The following is untested, (I just wrote it) but it should work. It
basicly wraps the new operator in a class template. Destructors
should be called approprately.

<headerFile>
/************************************************************
* Written by Adrian Hawryluk (C) Mar 6, 2007
* ----------------------------------------------------------
* You may use and add to this free of charge, but
* please keep this header intact, and if you modify
* please share your mods with everyone else.
*
* Usage:
*
* int * integer = alloc<int>::newObj();
* cout << allocBase::totalBytesAllocated() << endl; // 4
* int * intArray = alloc<int>::newObjArray(20);
* cout << allocBase::totalBytesAllocated() << endl; // 80
*
* class foo {
* int bar;
* public: ~foo() {}
* };
*
* foo * fooArray = alloc<foo>::newObjArray(20);
* cout << allocBase::totalBytesAllocated() << endl; // 84?
*
************************************************************/
class allocBase
{
static size_t bytesAllocatedSoFar;
public:
static size_t totalBytesAllocated() { return bytesAllocatedSoFar; }
};

template<class T>
class alloc{
T obj;
void * operator new(size_t size) { bytesAllocatedSoFar += size;
return ::eek:perator new(size); }
void * operator new[](size_t size) { bytesAllocatedSoFar += size;
return ::eek:perator new(size); }

public:
static T* newObj() { return reinterpret_cast<T*>(new T()); }
static T* newObjArray(int numberOfElements) { return
reinterpret_cast<T*>(new T[numberOfElements]); }
};
</headerFile>

<sourceFile>
size_t allocBase::bytesAllocatedSoFar = 0;
</sourceFile>

Enjoy,


Adrian
 
A

adrian.hawryluk

Sorry Adrian I wasn't clear. I am only interested in the memory used
by objects of class A. So for example if they are 100 objects of class
A which are created all with different sizes for floatData & data, I
want to know how memory is used by these 100 objects. This is why I
wanted to avoid using some sort of memory manager class that would
have new and delete overloaded.
My question was also about these extra bits that the new operator
seems to control to save info about the size of the byte arrays it has
created. I was wondering if that info could be accessed somehow, so
one could get that value from there !

First off, the new operator does not 'control' the number of bytes it
allocates, unless by control, you mean add to beyond what the compiler
is going to add to it. I.e. I stated that there could be a size_t
value at the begining of an array, this is done by the compiler, not
the new operator. The new operator is passed the size the compiler
needs to do its thing, and as stated by Ron, it is implementation
dependent. However, the new operator can add extra stuff if it wants,
as long as the returned pointer points to the space that the compiler
can use.

The following is untested, (I just wrote it) but it should work. It
basicly wraps the new operator in a class template. Destructors
should be called approprately.

<headerFile>
/************************************************************
* Written by Adrian Hawryluk (C) Mar 6, 2007
* ----------------------------------------------------------
* You may use and add to this free of charge, but
* please keep this header intact, and if you modify
* please share your mods with everyone else.
*
* Usage:
*
* int * integer = alloc<int>::newObj();
* cout << allocBase::totalBytesAllocated() << endl; // 4
* int * intArray = alloc<int>::newObjArray(20);
* cout << allocBase::totalBytesAllocated() << endl; // 80
*
* class foo {
* int bar;
* public: ~foo() {}
* };
*
* foo * fooArray = alloc<foo>::newObjArray(20);
* cout << allocBase::totalBytesAllocated() << endl; // 84?
*
************************************************************/
class allocBase
{
static size_t bytesAllocatedSoFar;
public:
static size_t totalBytesAllocated() { return bytesAllocatedSoFar; }

};

template<class T>
class alloc{
T obj;
void * operator new(size_t size) { bytesAllocatedSoFar += size;
return ::eek:perator new(size); }
void * operator new[](size_t size) { bytesAllocatedSoFar += size;
return ::eek:perator new(size); }

Er, I think that I should be newing alloc<T>'s not T's.

public:
static T* newObj() { return reinterpret_cast<T*>(new alloc<T>()); }
static T* newObjArray(int numberOfElements) { return
reinterpret_cast said:
public:
static T* newObj() { return reinterpret_cast<T*>(new T()); }
static T* newObjArray(int numberOfElements) { return
reinterpret_cast<T*>(new T[numberOfElements]); }};

</headerFile>

<sourceFile>
size_t allocBase::bytesAllocatedSoFar = 0;
</sourceFile>

Enjoy,

Adrian
 
M

mast2as

First off, the new operator does not 'control' the number of bytes it
allocates, unless by control, you mean add to beyond what the compiler
is going to add to it. I.e. I stated that there could be a size_t
....

Thanks Adrian,
Yes I had read that this was managed by the compiler indeed. I guess
that ansers my question well. Unless i add extra stuff as you say to
new operator, there's no more 'direct' way to get that information.
Thanks a lot for your help.
 
A

adrian.hawryluk

<headerFile>
/************************************************************
* Written by Adrian Hawryluk (C) Mar 6, 2007
* ----------------------------------------------------------
* You may use and add to this free of charge, but
* please keep this header intact, and if you modify
* please share your mods with everyone else.
*
* Usage:
*
* int * integer = alloc<int>::newObj();
* cout << allocBase::totalBytesAllocated() << endl; // 4
* int * intArray = alloc<int>::newObjArray(20);
* cout << allocBase::totalBytesAllocated() << endl; // 80
*
* class foo {
* int bar;
* public: ~foo() {}
* };
*
* foo * fooArray = alloc<foo>::newObjArray(20);
* cout << allocBase::totalBytesAllocated() << endl; // 84?
*
************************************************************/

This should read:

/************************************************************
* Written by Adrian Hawryluk (C) Mar 6, 2007
* ----------------------------------------------------------
* You may use and add to this free of charge, but
* please keep this header intact, and if you modify
* please share your mods with everyone else.
*
* Usage:
*
* int * integer = alloc<int>::newObj();
* cout << allocBase::totalBytesAllocated() << endl; // 4
* int * intArray = alloc<int>::newObjArray(20);
* cout << allocBase::totalBytesAllocated() << endl; // 84 (80 + 4)
*
* class foo {
* int bar;
* public: ~foo() {}
* };
*
* foo * fooArray = alloc<foo>::newObjArray(20);
* cout << allocBase::totalBytesAllocated() << endl; // 168? (84? +
84)?
*
************************************************************/


Adrian
 
A

adrian.hawryluk

...

Thanks Adrian,
Yes I had read that this was managed by the compiler indeed. I guess
that ansers my question well. Unless i add extra stuff as you say to
new operator, there's no more 'direct' way to get that information.
Thanks a lot for your help.

So your question is answered? Glad to have helped.


Adrian
 
A

AdrianH

In case anybody is interested, here is a complete and tested version
of what I was describing above.

<headerFile>
/**************************************************************
* Written by Adrian Hawryluk (C) Mar 6, 2007
* -------------------------------------------------------------
* You may use and add to this free of charge, but
* please keep this header intact, and if you modify
* please share your mods with everyone else.
*
* Usage:
*
* int * integer = alloc<int>::newObj(3);
* cout << allocBase::totalBytesAllocated() // 4
* << endl
* << "*integer = " << *integer << endl;
* delete integer;
*
* int * intArray = alloc<int>::newObjArray(20);
* cout << allocBase::totalBytesAllocated() // 84 (80 + 4)
* << endl
* << "*intArray = " << *intArray << endl;
* delete[] intArray;
*
* // Class located outside of the function where this code
* // is running.
* class foo {
* int bar;
* public:
* ~foo() {}
* };
*
* foo * fooArray = alloc<foo>::newObjArray(20);
* cout << allocBase::totalBytesAllocated() // 168? (84? + 84)
* << endl;
* // ? indicates that the returned value is compiler dependent
* delete[] fooArray;
*
**************************************************************/
class allocBase
{
protected:
static size_t bytesAllocatedSoFar;
public:
static size_t totalBytesAllocated() { return bytesAllocatedSoFar; }

};

template<class T>
class alloc : public allocBase {
T obj;

void * operator new(size_t size)
{
bytesAllocatedSoFar += size;
return ::eek:perator new(size);
}

void * operator new[](size_t size) {
bytesAllocatedSoFar += size;
return ::eek:perator new(size);
}

public:
static T* newObj()
{
return reinterpret_cast<T*>(new alloc<T>());
}

static T* newObjArray(int numberOfElements)
{
return reinterpret_cast<T*>(new alloc<T>[numberOfElements]());
}

// creates a new object and assigns it the value objToCopy
// requires that T::eek:perator=(T const&) or copy constructor is
defined
static T* newObj(T const & objToCopy)
{
T* tmp = reinterpret_cast<T*>(new alloc<T>());
*tmp = objToCopy;
return tmp;
}
};
</headerFile>

<sourceFile>
size_t allocBase::bytesAllocatedSoFar = 0;
</sourceFile>

Enjoy.


Adrian
 

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
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top