Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Test Dynamic Memory

Reply
Thread Tools

Test Dynamic Memory

 
 
Immortal Nephi
Guest
Posts: n/a
 
      12-13-2009
I notice that some codes do not have to test dynamic memory to
determine if dynamic memory is available or not. It is said in Deitel
How to Program C++ book.

Is it necessary to test dynamic memory if memory is very small like
less than 256 bytes? The test should fail and prevent you from doing
class constructor.

array class is already constructed before dynamic memory is tested.
If it fails, error message is displayed before exit() function
terminates the program. If I decide to allow the program running
after dynamic memory reported out of memory, then array class should
use destructor to clean up all data members and release array class
from the memory.

For example:

class array
{
public:

array( int size )
{
m_pArray = new int[ size ];
m_size = size;

if( m_pArray == 0 )
{
// Display Error Message -- out of memory
// Close other application and try again or
// use exit() function

// if( yes )
// exit();
// else ( no and continue )
m_bOutofMemory = true;
return;
}
}

~array()
{
if( m_pArray != 0 )
{
delete [] m_pArray;
m_pArray = 0;
}
}

bool TestMemory()
{
return m_bOutofMemory;
}

private:
int m_size;
int *m_pArray;
bool m_bOutofMemory;
};

int main()
{
array *a = new array( 5 );
if( a->TestMemory() == true )
delete a;

// Continue the program after
// exit() function is not invoked.

system( "pause");
return 0;
}
 
Reply With Quote
 
 
 
 
joseph cook
Guest
Posts: n/a
 
      12-13-2009
On Dec 13, 3:10*pm, Immortal Nephi <Immortal_Ne...@hotmail.com> wrote:
> I notice that some codes do not have to test dynamic memory to
> determine if dynamic memory is available or not. *It is said in Deitel
> How to Program C++ book.
>
> Is it necessary to test dynamic memory if memory is very small like
> less than 256 bytes? *The test should fail and prevent you from doing
> class constructor.
>


Amusingly enough, in C++, the regular new operator can never return 0,
so any test is useless. (A failed allocation will instead throw an
exception).

Of course, if you are working on some embedded systems that may have
disabled exceptions, check your documentation.
Joe Cook
 
Reply With Quote
 
 
 
 
peter koch
Guest
Posts: n/a
 
      12-13-2009
On 13 Dec., 21:10, Immortal Nephi <Immortal_Ne...@hotmail.com> wrote:
> I notice that some codes do not have to test dynamic memory to
> determine if dynamic memory is available or not. *It is said in Deitel
> How to Program C++ book.


If it says so, it is a bad book.

>
> Is it necessary to test dynamic memory if memory is very small like
> less than 256 bytes? *The test should fail and prevent you from doing
> class constructor.


If new fails, standard behaviour is to throw std::bad_alloc. Some very
old compilers got that wrong, noticeably VC6.0. If you use that
compiler and can't change, you can change a setting to make it
standards-compliant in that respect.

>
> array class is already constructed before dynamic memory is tested.
> If it fails, error message is displayed before exit() function
> terminates the program. *If I decide to allow the program running
> after dynamic memory reported out of memory, then array class should
> use destructor to clean up all data members and release array class
> from the memory.


You do realize, that you are just creating a dumped-down version of
std::vector? So your class is useless if not as an exercise. Also, you
are missing a lot of stuff - an assignment operator and a copy
constructor needs to be written.

>
> For example:
>
> class array
> {
> public:
>
> * * * * array( int size )
> * * * * {
> * * * * * * * * m_pArray = new int[ size ];
> * * * * * * * * m_size = size;
>
> * * * * * * * * if( m_pArray == 0 )
> * * * * * * * * {
> * * * * * * * * * * * * // Display Error Message -- out of memory
> * * * * * * * * * * * * // Close other application and try again or
> * * * * * * * * * * * * // use exit() function


This behaviour is better delegated into the new_handler function.

>
> * * * * * * * * * * * * // if( yes )
> * * * * * * * * * * * * // exit();
> * * * * * * * * * * * * // else ( no and continue )
> * * * * * * * * * * * * m_bOutofMemory = true;
> * * * * * * * * * * * * return;
> * * * * * * * * }
> * * * * }


Prefer initialization rather than assignment. Your constructor should
be
array( int size ): m_size(size),m_pArray(new int[ size ]) {}

Also notice that m_bOutofMemory only gets initialised in case there is
a memory leak, so you are likely to run into undefined behaviour in
TestMemory.

>
> * * * * ~array()
> * * * * {
> * * * * * * * * if( m_pArray != 0 )


There is no need for this check.

> * * * * * * * * {
> * * * * * * * * * * * * delete [] m_pArray;
> * * * * * * * * * * * * m_pArray = 0;


And no need for this assignment.

> * * * * * * * * }
> * * * * }
>
> * * * * bool TestMemory()
> * * * * {
> * * * * * * * * return m_bOutofMemory;
> * * * * }
>
> private:
> * * * * int m_size;
> * * * * int *m_pArray;
> * * * * bool m_bOutofMemory;


That hungarian notation really creeps me out.

>
> };
>
> int main()
> {
> * * * * array *a = new array( 5 );


Why do you want to allocate a dynamically? This is just silly. Use
array a(5);

> * * * * if( a->TestMemory() == true )


Why do you compare to true - this is just obfuscation. Prefer:
if( a->TestMemory() )

> * * * * * * * * delete a;
>
> * * * * // Continue the program after
> * * * * // exit() function is not invoked.
>
> * * * * system( "pause");
> * * * * return 0;


Here you have a memory leak - because of the dynamic allocation of a.

>
>
>
> }

 
Reply With Quote
 
Immortal Nephi
Guest
Posts: n/a
 
      12-13-2009
On Dec 13, 3:16*pm, peter koch <peter.koch.lar...@gmail.com> wrote:
> On 13 Dec., 21:10, Immortal Nephi <Immortal_Ne...@hotmail.com> wrote:
>
> > I notice that some codes do not have to test dynamic memory to
> > determine if dynamic memory is available or not. *It is said in Deitel
> > How to Program C++ book.

>
> If it says so, it is a bad book.
>
>
>
> > Is it necessary to test dynamic memory if memory is very small like
> > less than 256 bytes? *The test should fail and prevent you from doing
> > class constructor.

>
> If new fails, standard behaviour is to throw std::bad_alloc. Some very
> old compilers got that wrong, noticeably VC6.0. If you use that
> compiler and can't change, you can change a setting to make it
> standards-compliant in that respect.
>
>
>
> > array class is already constructed before dynamic memory is tested.
> > If it fails, error message is displayed before exit() function
> > terminates the program. *If I decide to allow the program running
> > after dynamic memory reported out of memory, then array class should
> > use destructor to clean up all data members and release array class
> > from the memory.

>
> You do realize, that you are just creating a dumped-down version of
> std::vector? So your class is useless if not as an exercise. Also, you
> are missing a lot of stuff - an assignment operator and a copy
> constructor needs to be written.


I build my own class. I don't need to use vector because I don't need
all the features such as search or insert element / remove element. I
suppose to put an assignment operator and a copy constructor to
private if I don't need to use them.

> > For example:

>
> > class array
> > {
> > public:

>
> > * * * * array( int size )
> > * * * * {
> > * * * * * * * * m_pArray = new int[ size ];
> > * * * * * * * * m_size = size;

>
> > * * * * * * * * if( m_pArray == 0 )
> > * * * * * * * * {
> > * * * * * * * * * * * * // Display Error Message -- out of memory
> > * * * * * * * * * * * * // Close other application and try again or
> > * * * * * * * * * * * * // use exit() function

>
> This behaviour is better delegated into the new_handler function.


Are you saying? I create some classes to build different objects and
put them into memory. For example, 5 different classes are
constructed successfully and are stored in memory. They will be
destructed after the program exits successfully. If one class
attempts to allocate more memory, then bad allocation must be returned
before new_handler exception is thrown. Correct?

I do not need to test to find out if new keyword returns a pointer
with bad allocation.
For example:

int *a = new int [1000];

if( a == )
exit();

I should use new_handler instead, but I have to use test condition to
find out if a is already allocated.

For example:

int *a = new int [1000];

// Do something

// Are ready to terminate your program. I have to clean up to
deallocate memory.
if( a != )
delete [] a;

> > * * * * * * * * * * * * // if( yes )
> > * * * * * * * * * * * * // exit();
> > * * * * * * * * * * * * // else ( no and continue )
> > * * * * * * * * * * * * m_bOutofMemory = true;
> > * * * * * * * * * * * * return;
> > * * * * * * * * }
> > * * * * }

>
> Prefer initialization rather than assignment. Your constructor should
> be
> * * * * array( int size ): m_size(size),m_pArray(new int[ size ]) {}
>
> Also notice that m_bOutofMemory only gets initialised in case there is
> a memory leak, so you are likely to run into undefined behaviour in
> TestMemory.
>
>
>
> > * * * * ~array()
> > * * * * {
> > * * * * * * * * if( m_pArray != 0 )

>
> There is no need for this check.
>
> > * * * * * * * * {
> > * * * * * * * * * * * * delete [] m_pArray;
> > * * * * * * * * * * * * m_pArray = 0;

>
> And no need for this assignment.
>
> > * * * * * * * * }
> > * * * * }

>
> > * * * * bool TestMemory()
> > * * * * {
> > * * * * * * * * return m_bOutofMemory;
> > * * * * }

>
> > private:
> > * * * * int m_size;
> > * * * * int *m_pArray;
> > * * * * bool m_bOutofMemory;

>
> That hungarian notation really creeps me out.

Please explain why you dislike hungarian notation. It provides you
more information when you need to know because there may be hundreds
or thosuands of variables. Anyway...

> > int main()
> > {
> > * * * * array *a = new array( 5 );

>
> Why do you want to allocate a dynamically? This is just silly. Use
> * * * * array a(5);
>
> > * * * * if( a->TestMemory() == true )

>
> Why do you compare to true - this is just obfuscation. Prefer:
> * * * * if( a->TestMemory() )
>
> > * * * * * * * * delete a;

>
> > * * * * // Continue the program after
> > * * * * // exit() function is not invoked.

>
> > * * * * system( "pause");
> > * * * * return 0;

>
> Here you have a memory leak - because of the dynamic allocation of a.


Here is another good example.

#include <iostream>
using std::cerr;
using std::cout;
using std::endl;

#include <new>
using std::set_new_handler;

#include <cstdlib>
using std::abort;
using std::exit;

class array
{
public:
array( int size ) : m_size( size ), m_pLargeArray( new long long
[ size ] )
{
cout << "array::constructor -- count: " << ++s_ObjectCount << endl;
}

~array()
{
cout << "array::destructor -- count: " << s_ObjectCount-- << endl;
delete [] m_pLargeArray;
}

private:
long long *m_pLargeArray;
int m_size;
static int s_ObjectCount;
};

int array::s_ObjectCount = 0;

void customNewHandler()
{
cerr << "customNewHandler was called.\n";
cerr << "Display Error: Not enough Memory.\n\n";
cerr << "Your C++ project must be terminated." << endl;

// abort();
exit( EXIT_SUCCESS );
}

int main()
{
set_new_handler( customNewHandler );

array a1( 50000000 ); // Success
array a2( 50000000 ); // Success
array a3( 50000000 ); // Success
array a4( 50000000 ); // Success
array a5( 50000000 ); // Failed -- bad memory allocation.

cout << "C++ project runs successful." << endl;

return 0;
}

If bad memory allocation is detected, then will exit() function does
its own responsibility to deallocate a1, a2, a3, and a4 from the
memory before program is terminated?

Do you suggest me to put new_handler exception in main.cpp only? All
other headers and source codes are included in main.cpp. new_handler
exception takes care to clean up the rest.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      12-14-2009
Immortal Nephi wrote:
> On Dec 13, 3:16 pm, peter koch <peter.koch.lar...@gmail.com> wrote:
>> On 13 Dec., 21:10, Immortal Nephi <Immortal_Ne...@hotmail.com> wrote:


>> You do realize, that you are just creating a dumped-down version of
>> std::vector? So your class is useless if not as an exercise. Also, you
>> are missing a lot of stuff - an assignment operator and a copy
>> constructor needs to be written.

>
> I build my own class. I don't need to use vector because I don't need
> all the features such as search or insert element / remove element. I
> suppose to put an assignment operator and a copy constructor to
> private if I don't need to use them.


There's no cost in not using what you don't need, there is cost in
reinventing wheels, so just use std::vector.

>>> For example:
>>> class array
>>> {
>>> public:
>>> array( int size )
>>> {
>>> m_pArray = new int[ size ];
>>> m_size = size;
>>> if( m_pArray == 0 )
>>> {
>>> // Display Error Message -- out of memory
>>> // Close other application and try again or
>>> // use exit() function

>> This behaviour is better delegated into the new_handler function.

>
> Are you saying? I create some classes to build different objects and
> put them into memory. For example, 5 different classes are
> constructed successfully and are stored in memory. They will be
> destructed after the program exits successfully. If one class
> attempts to allocate more memory, then bad allocation must be returned
> before new_handler exception is thrown. Correct?


If new fails, std::bad_alloc will be thrown. If you provide a
new_handler function, it will be called.

On a hosted environment, any allocated memory will be freed when the
process terminates.

> I do not need to test to find out if new keyword returns a pointer
> with bad allocation.


Correct.

>> That hungarian notation really creeps me out.


> Please explain why you dislike hungarian notation. It provides you
> more information when you need to know because there may be hundreds
> or thosuands of variables. Anyway...


It creeps out a lot of people. No sane class or function has hundreds
of variables.

>
> Here is another good example.
>

<snip code>
>
> If bad memory allocation is detected, then will exit() function does
> its own responsibility to deallocate a1, a2, a3, and a4 from the
> memory before program is terminated?


See above.

> Do you suggest me to put new_handler exception in main.cpp only? All
> other headers and source codes are included in main.cpp. new_handler
> exception takes care to clean up the rest.


You only have to call set_new_handler once.

--
Ian Collins
 
Reply With Quote
 
Immortal Nephi
Guest
Posts: n/a
 
      12-14-2009
On Dec 13, 10:43*pm, Ian Collins <ian-n...@hotmail.com> wrote:
> Immortal Nephi wrote:
> > On Dec 13, 3:16 pm, peter koch <peter.koch.lar...@gmail.com> wrote:
> >> On 13 Dec., 21:10, Immortal Nephi <Immortal_Ne...@hotmail.com> wrote:
> >> You do realize, that you are just creating a dumped-down version of
> >> std::vector? So your class is useless if not as an exercise. Also, you
> >> are missing a lot of stuff - an assignment operator and a copy
> >> constructor needs to be written.

>
> > I build my own class. *I don't need to use vector because I don't need
> > all the features such as search or insert element / remove element. *I
> > suppose to put an assignment operator and a copy constructor to
> > private if I don't need to use them.

>
> There's no cost in not using what you don't need, there is cost in
> reinventing wheels, so just use std::vector.


Ok. Do you think that I should use std::vector if list of Multi-
Dimension array contain bitmap images such as font image or picture
image? Perhaps, search feature is needed because some strings have
individual characters and each character in the string is searched
(scanned) before 2-D array with font image is selected to be displayed
to the screen. Also, 2-D array with font image will be copied into
Pixel Buffer before Pixel Buffer is used with DirectX or other graphic
engines.

 
Reply With Quote
 
aku ankka
Guest
Posts: n/a
 
      12-14-2009
On Dec 14, 1:52*am, Immortal Nephi <Immortal_Ne...@hotmail.com> wrote:
>
> I build my own class. *I don't need to use vector because I don't need
> all the features such as search or insert element / remove element.


.... yet.
 
Reply With Quote
 
aku ankka
Guest
Posts: n/a
 
      12-14-2009
On Dec 14, 8:10*am, Immortal Nephi <Immortal_Ne...@hotmail.com> wrote:
> Ok. *Do you think that I should use std::vector if list of Multi-
> Dimension array contain bitmap images such as font image or picture
> image? *Perhaps, search feature is needed because some strings have
> individual characters and each character in the string is searched
> (scanned) before 2-D array with font image is selected to be displayed
> to the screen. *Also, 2-D array with font image will be copied into
> Pixel Buffer before Pixel Buffer is used with DirectX or other graphic
> engines.


I think, that you need image/surface class where you store information
about the surfaces: width, height, stride, format at least. And the
image data; whether it is std::vector or char* doesn't make much
difference.

OK; so the std::vector will have methods that you are not going to
use, big deal, so what. I wouldn't write my own array class to replace
the vector, though. I'd just use char*. Oh, right - that's what I do!

If I were to use std::vector, it would be std::vector<char> or
std::vector<uint8>, where uint8 is obviously octet, *piip* the
platforms where char ISN'T octet! <- if this isn't mentioned, ****
storm will result in this NG, no offence to anyone. >B)
 
Reply With Quote
 
Immortal Nephi
Guest
Posts: n/a
 
      12-14-2009
On Dec 14, 2:00*am, aku ankka <ju...@liimatta.org> wrote:
> On Dec 14, 8:10*am, Immortal Nephi <Immortal_Ne...@hotmail.com> wrote:
>
> > Ok. *Do you think that I should use std::vector if list of Multi-
> > Dimension array contain bitmap images such as font image or picture
> > image? *Perhaps, search feature is needed because some strings have
> > individual characters and each character in the string is searched
> > (scanned) before 2-D array with font image is selected to be displayed
> > to the screen. *Also, 2-D array with font image will be copied into
> > Pixel Buffer before Pixel Buffer is used with DirectX or other graphic
> > engines.

>
> I think, that you need image/surface class where you store information
> about the surfaces: width, height, stride, format at least. And the
> image data; whether it is std::vector or char* doesn't make much
> difference.
>
> OK; so the std::vector will have methods that you are not going to
> use, big deal, so what. I wouldn't write my own array class to replace
> the vector, though. I'd just use char*. Oh, right - that's what I do!
>
> If I were to use std::vector, it would be std::vector<char> or
> std::vector<uint8>, where uint8 is obviously octet, *piip* the
> platforms where char ISN'T octet! <- if this isn't mentioned, ****
> storm will result in this NG, no offence to anyone. >B)


I hate signed integer on all sizes. I zlways use unsigned integer.
Often, strings use signed char or signed wchar_t. Combining unsigned
integer and signed integer are problemtic. I always declare unsigned
char to string because sometimes, I want to use between 128-256 range
ASCII or unicode.

I agree with you. You should declare and define unsigned char array
to hold bitmap image in the global scope. I would strongly recommend
you to construct array class in your own. Declare unsigned char to
static const inside array class. In another way, you can use pointer
to unsigned char when it uses dynamic memory. You use fstream to
read / load raw bitmap image into dynamic memory. You can use either
choice.

For example:

// Header
class CFontImage
{
private:
static const unsigned char fonts[ 256 ] [ 8 * 8 ];
// or...
unsigned char *pFonts; // Load raw bitmap image

public:
// Write your member functions to maniuplate fonts
};

// Source code

const unsigned char CFontImage::fonts[ 256 ] [ 8 * 8 ] =
{
{....},
{....},
etc
};

The member function in the CFontImage class reads data from string
class and then range ASCII is selected in the fonts array before 8 x 8
font pixel is copied into surface class.

Very simple! Much easier to know where member functions belong to
CFontImage class rather than use global scope.

 
Reply With Quote
 
aku ankka
Guest
Posts: n/a
 
      12-15-2009
On Dec 14, 7:17*pm, Immortal Nephi <Immortal_Ne...@hotmail.com> wrote:
> I agree with you. *You should declare and define unsigned char array
> to hold bitmap image in the global scope. *I would strongly recommend
> you to construct array class in your own. *Declare unsigned char to
> static const inside array class. *In another way, you can use pointer
> to unsigned char when it uses dynamic memory. *You use fstream to
> read / load raw bitmap image into dynamic memory. *You can use either
> choice.


Heap is heaps better for surface data. Global variables are rarely
needed at all and won't work very well on few mobile environments /
platforms (globals and statics are tricky on BREW and SYMBIAN).

I have abstraction for surfaces, where surface class is a reference
(not in C++ sense of the word) to the image data. The surface class
has a pointer to the image data, width, height, stride and format.

That is all information I need to communicate with different API's,
OpenGL; Direct3D, OpenCL and so on. The surface class is just
description of the image data, nothing more. Examples:

1. Create surface from a file

surface* s = surface::create(L"bukkake.jpg"´, pixelformat::argb888;
uint32* image = s->lock<uint32>();
// TODO: do something with image
s->unlock();
s->release();

The pixelformat is complex object which describes the pixelformats
with masks for color components, has type enumeration for components
(uint32, float, half, etc..), fourcc for compressed data and so on and
on. The pixelformat::argb8888 is pre-defined format for convernience
(there are obviously more but that one is very common

This approach reads the file, decodes the bitstream and creates a new
surface object. Pretty obvious. The surface "owns" the data, so the
release() method will deallocate the image.

2. Creating a reference to existing image..

void foo(char* image)
{
// we "know" that the raw data is in RGB565 format
surface* s = surface::create(320, 240, pixelformat::rgb565, image,
320 * sizeof(uint16));
// ... do something ..
s->release();
}

This time around the s->release WON'T free the image data, since this
surface is just describing (=reference) to data elsewhere.

What if we want to create a surface which DOES "own" the image data?

3. Create surface and allocate memory

surface* s = bitmap::create(640, 480, format);
s->release();

And so on. The "API" is same for the surfaces; you can lock them, read
and write to the image data the surface is describing, serialize
(write into file, memory buffer, etc.).. clear the surface, blit it to
other surface (with scaling, filtering, etc).

The surface system supports bitmaps, surfaces, cubemaps, 3d textures,
2d textures, you name it. The code is portable, however, I only have
tested it on OS X, Linux (32 bit and 64 bit), IRIX and Windows (32 bit
and 64 bit). So basically 32 bit and 64 bit, little and big endian
systems are covered.

The "system" might sound complicated, but it's not, really. Simple
inheritance to support different flavors of surfaces.

I have a font system as well, but it's based on textures and unicode
(can render different languages than just Latin). Latin is easy if we
use "char"; just use a look-up-table and we're done. Unicode requires
more eloborate caching scheme since we don't know in advance which
glyphs might be needed.

First, we need to cache the glygps.. for this I use a simple binary
tree for lookup. If we have a cache miss, we need to allocate texels
from existing texture. So we need a surface manager (2D memory
allocator). It's more efficient to use a single texture and spill the
least recently used glyphs out (so I use LRU eviction policy, sue me)
rathen than trying to use more textures.

The cache size (=texture size) is configurable, I usually am very
happy with 512x512 texture, but 2048x2048 would probably never spill
in practical application.

The surface manager does NOT have de-fragmenting, I use fixed tile
size which I determine from the font size. This wastes maybe 5-10% of
texture area but eliminates the need for de-fragmenting so it's a good
tradeoff.

If I were doing application just for Latin character set, a simple
lookup table approach would be much simpler. But I have to support
Japanese, Korean, etc. I don't know those languages, but filenames in
those languages MUST work in the User Interface which is rendered with
OpenGL, so, Unicode font system is a Must.

Speaking of unicode, supporting it with c++ is a bit .. let's not talk
about that.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
test test test richard Computer Support 3 01-24-2007 05:18 AM
TEST TEST Test...Blah Blah Blah generalbatguano@pacbell.net Computer Support 2 09-15-2006 03:47 AM
TEST TEST Test...Blah Blah Blah Generalbatguano@pacbell.net Computer Support 6 09-13-2006 01:53 AM
TEST TEST TEST Gazwad Computer Support 2 09-05-2003 07:32 PM
test test test test test test test Computer Support 2 07-02-2003 06:02 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57