The .bmp file format

The .bmp file format

Introduction:

The .bmp file format (sometimes also saved as .dib) is the standard for a Windows 3.0 or later DIB (device independent bitmap) file. It may use compression (though I never came across a compressed .bmp-file) and is (by itself) not capable of storing animation. However, you can animate a bitmap using different methods but you have to write the code which performs the animation. There are different ways to compress a .bmp-file, but I won't explain them here because they are so rarely used. The image data itself can either contain pointers to entries in a color table or literal RGB values (this is explained later).

Basic structure:

A .bmp file contains of the following data structures:

BITMAPFILEHEADER    bmfh;
BITMAPINFOHEADER    bmih;
RGBQUAD             aColors[];
BYTE                aBitmapBits[];

bmfh contains some information about the bitmap file (about the file, not about the bitmap itself). bmih contains information about the bitmap such as size, colors,... The aColors array contains a color table. The rest is the image data, which format is specified by the bmih structure.

Exact structure:

The following tables give exact information about the data structures and also contain the settings for a bitmap with the following dimensions: size 100x100, 256 colors, no compression. The start-value is the position of the byte in the file at which the explained data element of the structure starts, the size-value contains the nuber of bytes used by this data element, the name-value is the name assigned to this data element by the Microsoft API documentation. Stdvalue stands for standard value. There actually is no such a thing as a standard value but this is the value Paint assigns to the data element if using the bitmap dimensions specified above (100x100x256). The meaning-column gives a short explanation of the purpose of this data element.

The BITMAPFILEHEADER:

start

size

name

stdvalue

purpose

1

2

bfType

19778

Must always be set to 'BM' to declare that this is a .bmp-file.

3

4

bfSize

??

Specifies the size of the file in bytes.

7

2

bfReserved1

0

Must always be set to zero.

9

2

bfReserved2

0

Must always be set to zero.

11

4

bfOffBits

1078

Specifies the offset from the beginning of the file to the bitmap data.

The BITMAPINFOHEADER:

start

size

name

stdvalue

purpose

15

4

biSize

40

Specifies the size of the BITMAPINFOHEADER structure, in bytes.

19

4

biWidth

100

Specifies the width of the image, in pixels.

23

4

biHeight

100

Specifies the height of the image, in pixels.

27

2

biPlanes

1

Specifies the number of planes of the target device, must be set to zero.

29

2

biBitCount

8

Specifies the number of bits per pixel.

31

4

biCompression

0

Specifies the type of compression, usually set to zero (no compression).

35

4

biSizeImage

0

Specifies the size of the image data, in bytes. If there is no compression, it is valid to set this member to zero.

39

4

biXPelsPerMeter

0

Specifies the horizontal pixels per meter on the designated target device, usually set to zero.

43

4

biYPelsPerMeter

0

Specifies the vertical pixels per meter on the designated target device, usually set to zero.

47

4

biClrUsed

0

Specifies the number of colors used in the bitmap, if set to zero the number of colors is calculated using the biBitCount member.

51

4

biClrImportant

0

Specifies the number of color that are 'important' for the bitmap, if set to zero, all colors are important.


Note that biBitCount actually specifies the color resolution of the bitmap. The possible values are: 1 (black/white); 4 (16 colors); 8 (256 colors); 24 (16.7 million colors). The biBitCount data element also decides if there is a color table in the file and how it looks like. In 1-bit mode the color table has to contain 2 entries (usually white and black). If a bit in the image data is clear, it points to the first palette entry. If the bit is set, it points to the second. In 4-bit mode the color table must contain 16 colors. Every byte in the image data represents two pixels. The byte is split into the higher 4 bits and the lower 4 bits and each value of them points to a palette entry. There are also standard colors for 16 colors mode (16 out of Windows 20
reserved colors (without the entries 8, 9, 246, 247)). Note that you do not need to use this standard colors if the bitmap is to be displayed on a screen which support 256 colors or more, however (nearly) every 4-bit image uses this standard colors. In 8-bit mode every byte represents a pixel. The value points to an entry in the color table which contains 256 entries (for details see Palettes in Windows. In 24-bit mode three bytes represent one pixel. The first byte represents the red part, the second the green and the third the blue part. There is no need for a palette because every pixel contains a literal RGB-value, so the palette is omitted.

The RGBQUAD array:

The following table shows a single RGBQUAD structure:

start

size

name

stdvalue

purpose

1

1

rgbBlue

-

Specifies the blue part of the color.

2

1

rgbGreen

-

Specifies the green part of the color.

3

1

rgbRed

-

Specifies the red part of the color.

4

1

rgbReserved

-

Must always be set to zero.


Note that the term palette does not refer to a RGBQUAD array, which is called color table instead. Also note that, in a color table (RGBQUAD), the specification for a color starts with the blue byte. In a palette a color always starts with the red byte. There is no simple way to map the whole color table into a LOGPALETTE structure, which you will need to display the bitmap. You will have to write a function that copies byte after byte.

The pixel data:

It depends on the BITMAPINFOHEADER structure how the pixel data is to be interpreted (see above).
It is important to know that the rows of a DIB are stored upside down. That means that the upper row which appears on the screen actually is the lowest row stored in the bitmap, a short example:


pixels displayed on the screen

pixels stored in .bmp-file




You do not need to turn around the rows manually. The API functions which also display the bitmap will do that for you automatically.
Another important thing is that the number of bytes in one row must always be adjusted to fit into the border of a multiple of four. You simply append zero bytes until the number of bytes in a row reaches a multiple of four, an example:

6 bytes that represent a row in the bitmap:

A0 37 F2 8B 31 C4

must be saved as:

A0 37 F2 8B 31 C4 00 00

to reach the multiple of four which is the next higher after six (eight). If you keep these few rules in mind while working with .bmp files it should be easy for you, to master it.

Steganography

//Steg.h
Designed and Implementation: Renjith G


/********************** header file*************************/
#define BUFSIZE 1024 //512
#define DATASIZE 64
#define STARTBYTE 64

/************type definition***********************/
/* typedefs */
typedef unsigned char UBYTE;

/***********struture definition********************/
struct steg_header
{
unsigned long datalen;
char key[10];
};

struct BMPFILEHEADER
{
unsigned char bfType; //2 Bitmap identifier. Must be 'BM'.
unsigned int bfSize; //4 Can be set to 0 for for uncompressed bitmaps, which is the kind we have.
short int bfReserved1;//2 Set to 0.
short int bfReserved2;//2 Set to 0.
unsigned int bfOffbits; //4 Specifies the location (in bytes) in the file of the image data.
// For our 8-bit bitmaps, this will be sizeof(BITMAPFILEHEADER) +
//sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * numPaletteEntries.
};


struct BMPINFOHEADER
{
unsigned int biSize; //4 This is the size of the BMPINFOHEADER structure. Thus, it is
//sizeof(BITMAPINFOHEADER).
unsigned int biWidth; //4 The width of the bitmap, in pixels.
unsigned int biHeight; //4 The height of the bitmap, in pixels.
short int biPlanes; //2 Set to 1.
short int biBitCount; //2 The bit depth of the bitmap. For 8-bit bitmaps, this is 8.
unsigned int biCompression; //4 Our bitmaps are uncompressed, so this field is set to 0.
unsigned int biSizeImage; //4 The size of the padded image, in bytes.
unsigned int biXPelsPerMeter; //4 Horizontal resolution, in pixels per meter, of device displaying bitmap. This number is not significant for us, and will be set to 0.
unsigned int biYPelsPerMeter; //4 Vertical resolution, in pixels per meter, of device displaying bitmap. This number is not significant for us, and will be set to 0.
unsigned int biClrUsed; //4 This indicates how many colors are in the palette.
unsigned int biClrImportant; //4 This indicates how many colors are needed to display the bitmap. We will set it to 0, indicating all colors should be used.

};
/********************************************************/



//Steg.cpp
Designed and Implementation: Renjith G

/*My Special Thanks to -----Peter Kieltyka----For the Main Idea of hiding Data
on LSB of Bitmap File. New program Modified and designed by renjith.
Creation Date ->Saturday, January 31, 2004, 10:48:42 PM
Last Modification ->Tuesday , March 02 , 2004, 10:44:54 PM
*/
#include "steg.h"
#include
#include
#include
//#include

/**************Function Prototypes*************************/

void MediaInfo(char *);
CheckMediaFile (FILE *);
void Eof(void);
void usage(char *);
int MaxCapacity(unsigned long);
int FileSize(FILE *);
int SteganoHide(char *, char *, char *, char *);
int SteganoExtract(char *, char *, char *);
/*************************Usage()*************************/
void usage(char *argv)
{
fprintf(stderr,
"\n\n"
"usage: \t\t To Hide\n"

"%s \n "
"\n\n"
"usage:\t\t To Extract\n"
"%s \n\n"
"\n\n"
"usage:\t\t To get Information about MediaFile File\n"
"%s <-i> "
"\n\n",argv,argv,argv);
exit(-1);
}
/******************EOF()*********************************/

void Eof(void)
{
puts("Error: End of file encountered - So aborting...\n");
}
/********************************************************/



/*********************************************************/
CheckMediaFile (FILE *fpin)
{
int b;

if ((b = getc (fpin)) == EOF)
Eof();
//printf("b=%d\n",b); /* ren check*/
return (UBYTE) b;
}
/****************Checking MaxCapacity()********************/
int MaxCapacity(unsigned long fsize)
{
return((fsize-STARTBYTE)/8);

}
/***************FileSize()***********************************/
int FileSize(FILE *fp)
{
unsigned long fsize;

(void)fseek(fp, 0, SEEK_END);
fsize = ftell(fp);
(void)fseek(fp, 0, SEEK_SET);
return(fsize);
}
/**********************************************************/
void MediaInfo(char *fin)
{

struct BMPINFOHEADER bmih;
FILE *fpin;
long int hresol,vresol;
unsigned long int value;

if((fpin = fopen(fin, "rb")) == NULL)
{
fprintf(stderr, "Error! Cannot open input file!\n");
exit(-1);
}

switch (CheckMediaFile (fpin))
{
case 'M':
break;
case 'A':
puts ("File is probably an OS/2 bitmap ARRAY.\n");
fclose(fpin);
break;

case 'B':
{
puts("\n\n");
puts("File is Probably a Bitmap!\n");
puts("Media File Information\n");
rewind(fpin); /*set file pointer to beginning
please refer linux man pages */
fseek(fpin,14,SEEK_SET);
fread(&value,4,1,fpin);
printf("Bitmap Type -->");
switch(value)
{
case 12:
puts(" Bitmap of OS/2 (1)");
break;
case 40:
puts(" Windows Bitmap");
break;
case 64:
puts(" Bitmap of OS/2 (2)");
break;
default:
puts(" Unknown Type");
break;
}
////////////////////////////////printf("VALUE =%ld\n",value);
rewind(fpin);
fseek(fpin,14,SEEK_SET);

fread(&bmih,sizeof(bmih),1,fpin);

printf("Size of %s = %dKB\n",fin,bmih.biSizeImage/1024);
printf("Width of Bitmap File = %d\n", bmih.biWidth );
printf("Height of Bitmap File = %d\n", bmih.biHeight);
hresol = bmih.biXPelsPerMeter/39.3700787401;
vresol = bmih.biYPelsPerMeter/39.3700787401;
printf("Horizontal Resolution = %ld dpi\n",hresol);
printf("Vertical Resolution = %ld dpi\n",vresol);
switch(bmih.biBitCount)
{
case 1:
puts ("Monochrome Image 1bit (2 color)\n");
break;
case 4:
puts ("VGA Image ->4bit (16 color)\n");
break;
case 8:
puts ("SVGA or greyscale ->8bit (256 color)\n");
break;
case 16:
puts ("High Color ->16bit (65536 colour)\n");
break;
case 24:
puts ("True Color ->24bit (16.7 Mio colour)\n");
break;
default:
printf ( "Unknown color depth = %i\n",bmih.biBitCount );
} /*End o 2nd switch*/
if(bmih.biCompression != 0) /*Refer 6th field of BMPinfoHeader structure */
printf("BitMap File <%s> is Compressed\n",fin);
else
printf("Bitmap File <%s> is UnCompressed\n",fin);

}
fclose(fpin);
// printf("file closed");

} /*End of 1st switch*/

}

/***********************SteganoHide()***********************/
/* notes:- when hiding:
a = (a & ~1) | (((b >> (7-k)) & 1) & 1);

this takes the bit of byte 'b' at location 'k' (k goes from 0-7, 0 being the LSB)
and stores it in the LSB of byte 'a'

*/

int SteganoHide(char *fin, char *fout, char *fdata, char *key)
{
FILE *fpin, *fpout, *fpdata;
unsigned long media,fhide;
struct steg_header steg = {0};
char data[DATASIZE];
char buf[BUFSIZE];
int c,n,i,k,x,j,h;
int mediatype;
int count;/*Media file Type */
if((fpin = fopen(fin, "rb")) == NULL)
{
fprintf(stderr, "Error! Cannot open input file!\n");
exit(-1);
}
if((fpout = fopen(fout, "wb")) == NULL)
{
fprintf(stderr, "Error! Cannot open output file!\n");
exit(-1);
}
if((fpdata = fopen(fdata, "rb")) == NULL)
{
fprintf(stderr, "Error! Cannot open %s!\n", fdata);
exit(-1);
}

mediatype = CheckMediaFile (fpin);
if(!(mediatype == 'B'))
{
printf("GETSREGABYTE = %d\n",mediatype);
fprintf(stderr, "Error! %s ->s Not a BITMAP File!\n", fin);
exit(-1);
}
media = FileSize(fpin);
fhide = FileSize(fpdata);

//if(MaxCapacity(FileSize(fpin)) < FileSize(fpdata))
if(MaxCapacity(media) < fhide)
{
printf("\nMedia size = %ld\n",media);
printf("File-to-Hide = %ld\n",fhide);
fprintf(stderr, "Error!! Hiding File %s will not fit in %s, %d Bytes Capacity!\n",
fdata,fin, MaxCapacity(media));
return(-1);
}

steg.datalen = FileSize(fpdata);
memcpy(steg.key, key, sizeof(steg.key));
puts("Please wait while Hiding............");
x = 0;
k = 0;
j = 0;
i = STARTBYTE;
h = sizeof(steg);
count=0;

while(n = fread(buf, 1, sizeof(buf), fpin)) /* total no of bytes read = size(buf) * 1 */
{
if(x != 0)
i = 0;

while(i < n)
{
if(j <= 0)
{
c = 0;
memset(data, 0, sizeof(data)); /* returns data */
j = fread(data+h, 1, sizeof(data)-h, fpdata);
// j = fread(data, 1, sizeof(data), fpdata);
// printf("j==================%d\n",j);

if(h != 0)
{
j += h;
memcpy(data, &steg, sizeof(steg));
h = 0;
}
}

if(j > 0)
{
printf("count=%d\n",count);
printf("the val buf[%d] =%d\n",i,buf[i]);
printf("The data[%d] =%d\n",c,(((data[c] >> (7-k)) & 1) & 1));


// printf("i=%d \t c=%d\n",i,c);

buf[i] = (buf[i] & ~1) | (((data[c] >> (7-k)) & 1) & 1);
printf("the val buf[%d] =%d\n\n\n",i,buf[i]);
count=count+1;

// getch();

k++;
//printf("buff %c\n",buf[i] );
if(k > 7)
{
k = 0;
c++;
j--;
}
}

i++;
} /* End Of While */

fwrite(buf, 1, n, fpout);
x += n;
}

fclose(fpin);
fclose(fpout);
fclose(fpdata);

return(0);
}

/****************Stegano Extraction()********************/
/* note to follow:- when extracting:
a = (a & ~(1 << (7-k))) | ((b & 1) << (7-k));

this assigns 'a' the LSB of 'b' to location 'k' (k goes from 0-7, 0 being the LSB)
*/
int SteganoExtract(char *fin, char *fout, char *key)
{
FILE *fpin, *fpout;
struct steg_header steg = {0};
char buf[BUFSIZE], data[DATASIZE], c;
int done,n,x,i,k,j;

if((fpin = fopen(fin, "rb")) == NULL)
{
fprintf(stderr, "Error! Cannot open input file!\n");
exit(-1);
}
if((fpout = fopen(fout, "wb")) == NULL)
{
fprintf(stderr, "Error! Cannot open output file!\n");
exit(-1);
}


// Get header
x = 0;
j = 0;
k = 0;
done = 0;
puts("Please wait while Extracting............");
memset(data, 0, sizeof(data));
while((n = fread(buf, 1, sizeof(buf), fpin)) && done == 0)
{
if(x == 0)
i = STARTBYTE;
else
i = 0;

while(i < n)
{
if(j < sizeof(steg))
{
data[j] = (data[j] & ~(1 << (7-k))) | ((buf[i] & 1) << (7-k));
k++;

if(k > 7)
{
k = 0;
j++;
}
}
else
{
done = 1;
break;
}

i++;
} /*end of While */

x += n;
}
memcpy(&steg, data, sizeof(steg));
(void)fseek(fpin, 0, SEEK_SET);

// Check key's
if(strcmp(steg.key, key))
{
printf("Incorrect Key! No data for you!\n");
fclose(fpin);
fclose(fpout);
return(-1);
}

// Get data
x = 0;
k = 0;
j = steg.datalen;
i = STARTBYTE+(sizeof(steg)*8);
while(n = fread(buf, 1, sizeof(buf), fpin))
{
if(x != 0)
i = 0;

while(i < n)
{
c = (c & ~(1 << (7-k))) | ((buf[i] & 1) << (7-k));
k++;

if(k > 7)
{
k = 0;
j--;
if(j >= 0)
fputc(c, fpout);
}

i++;
}

x += n;
}

fclose(fpin);
fclose(fpout);

return(0);
}

/********************Main()******************************/

int main(int argc, char **argv)
{
///int c; /////////////////////////
if(argc <> 5)

usage(argv[0]);
if(argc == 3)
{
if(strcmp (argv[1],"-i") == 0)
{
//puts("in hai");
MediaInfo(argv[2]);
exit(-1);
}
else
puts("out hai");
usage(argv[0]);
exit(-1);
///////////////////////////srecmp(argv[2],"-i")==0?usage(argv[0]):exit(-1));
}
if(argc == 4)
{
if(strlen(argv[3]) > 10)
{
printf("Sorry, the key cannot be greater then 10 characters long!\n");
exit(-1);
}

SteganoExtract(argv[1], argv[2], argv[3]);
}
else
{
if(strlen(argv[4]) > 10)
{
printf("Sorry, the key cannot be greater then 10 characters long!\n");
exit(-1);
}

SteganoHide(argv[1], argv[2], argv[3], argv[4]);
}
exit(0);
}
/**********************end of main()************************/






Fork()

#include
#include
main()
{
int ret;
ret = fork();
if(ret == 0)
{ printf("\n");
printf("Current Process pid =%d(Executed by child\n",getpid());
printf("\n");
printf("Parent Process pid =%d(Executed by child)\n",getppid());
printf("\n");
}
else
{
wait();
printf("\n");
printf("Current Process pid =%d(Executed by child\n",getpid());
printf("\n");
printf("Parent Process pid =%d(Executed By parent\n",getppid());
printf("\n");
}
}

Queue

#include
# define max 3

struct queue
{
int queue[max];
int f,r;
}q;

main()
{
int ch,k=1;
q.f=0;
q.r=-1;
while(k==1)
{printf("\t\t MENU\n"
"\t1.INSERT\n"
"\t2.DELETE\n"
"\t3.DISPLAY\n"
"\t4.EXIT\n"
"\tEnter Your Choice:\n");
scanf("%d",&ch);
switch(ch)
{
case 1:
insert();
break;
case 2:
delete();
break;
case 3:
display();
break;
case 4:
k=0;
exit(0);
default :
printf("Invalid choice");
}
}
}

insert()
{
int val;
if(q.r == max)
{
printf("QUEUE Overflow");
}
else
{
q.r++;
printf("enter the val:");
scanf("%d",&val);
q.queue[q.r]=val;
}
//if(q.f == -1)
// q.f = 0;
}


delete()
{
if(q.f == 0 && q.r ==0)
{
printf("Under flow");
}
printf("Deleted item:%d\n",q.queue[q.f]);
if(q.r == q.f)
{
q.r=q.f=0;
// printf("Deleted item:%d\n",q.queue[q.f]);

}
else
q.f++;
}

display()
{
int i;
//printf("q.f=%d q.r =%d",q.f,q.r);
if(q.r == -1)
printf("EMPTy Queue");
else
{
for(i=q.f;i<=q.r;i++)
{
printf("Queue[%d]=%d\n",i,q.queue[i]);
}
}
}

Insertion Sort

//INSERTION SORT
#include
//#include
#include
main ()
{
int a[100], n, s[100], temp, j, i;
printf ("Enter the number of elements in the array(max no:=100)\n");
scanf ("%d", &n);
printf ("eneter the elements :");
for (i = 0; i < n; i++)
{
scanf ("%d", &a[i]);
}
s[0] = a[0];
for (i = 1; i < n; i++)
{
temp = a[i];
j = i - 1;
while ((s[j] > temp) && (j >= 0))
{
s[j + 1] = s[j];
j--;
}
s[j + 1] = temp;
}
printf ("the sorted array is:\n");
for (i = 0; i < n; i++)
{
printf ("\n");
printf ("%d", s[i]);
}

}

Circular Queue

#include
# define max 4

struct cque
{
int cque[max];
int f,r;
}c;

main()
{
c.f=0;
c.r=-1;
int k=1,ch;
while(k==1)
{printf("\t\t MENU\n"
"\t1.INSERT\n"
"\t2.DELETE\n"
"\t3.DISPLAY\n"
"\t4.EXIT\n"
"\tEnter Your Choice:\n");
scanf("%d",&ch);
switch(ch)
{
case 1:
insert();
break;
case 2:
delete();
break;
case 3:
// display();
break;
case 4:
k=0;
exit(0);
default :
printf("Invalid choice");
}
}
}

insert()
{
int val;
if((c.f == 1 && c.r == max)) //|| c.f = c.r + 1)
{
printf("Over Flow");
}
else if(c.f == 0)
c.f=c.r=1;
else if(c.r == max)
c.r = 1;
else
c.r = c.r + 1;
printf("Enter the value:");
scanf("%d",&val);
c.cque[c.r] = val;
}

delete()
{
if(c.f == 0)
{
printf("Under flow");
}
else
{
printf("deleted Item=%d",c.cque[c.f]);
}
if(c.f == c.r)
c.f = c.r= 0;
else if(c.f = max)
c.f = 1;
else
c.f = c.f + 1;
}

BMP EdgeDetection (Monocrome Image)

//BMP.h
// Created by Renjith and Sajith


#include
#include

#pragma once

struct _v3f
{
_v3f( ): x(0.0f), y(0.0f), z(0.0f) //default constructor
{ };
_v3f(float xx, float yy, float zz )//3 argument constructor
{
x = xx;
y = yy;
z = zz;
}
float x;
float y;
float z;
};

class CBmp
{

//Type definitions
typedef std::vector<_v3f> vec3f;
typedef std::vector vecint;
typedef std::string _str;

//Member data
HBITMAP m_hBitmap;
BYTE* m_bmpBuffer;
int m_height;
int m_width;
int m_side;
int m_bgcolor;
bool m_eightblocks[8];
DWORD m_sizeBuffered;
vec3f m_vecCords;
vecint m_vecPixels;

public:
//constructor && destructor
CBmp (void);
virtual ~CBmp(void);

//Member functions
void Load (_str path, int nSide);
void BlacknWhite(int nBGVal);
void Process_BMPdata();
void Store_BMPdata();
int FindBackGround();
bool SetSize_BMPbuffer(long size);
long GetSize_BMPimage();
bool InttoBoolConverter(int nData);
vec3f Edges_BMPimage(){return m_vecCords;};


protected:
void Free ()
{
if (m_hBitmap)
::DeleteObject (m_hBitmap);
}
};



//BMP.cpp
// Created by Renjith and Sajith


#include "Bmp.h"

using namespace std;

CBmp::CBmp(void):m_hBitmap (0)
{
}

CBmp::~CBmp(void)
{
Free();
}

void CBmp::Load (string path, int nSide)
{
Free ();//here confirms that the handle is deleted first(freed)
m_hBitmap = (HBITMAP) ::LoadImage (0, path.c_str(),IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if (m_hBitmap == 0)
{
MessageBox(NULL,"Loading Bitmap Handle Failed... Exiting","",0) ;
return;
}

//set the m_side
m_side = nSide;

//Get the size of BMP
long size = this->GetSize_BMPimage();

//Set the size of buffer for storing BMP data
if(!this->SetSize_BMPbuffer(size))
return;

this->Store_BMPdata();
}

void CBmp::Store_BMPdata()
{
m_sizeBuffered = GetBitmapBits(m_hBitmap,m_width*m_height,(BYTE*)m_bmpBuffer);

if(0 == m_sizeBuffered){
MessageBox(NULL,"Error copying BMP data to Buffer","",0);
return;
}
//find the background pixel value
m_bgcolor = this->FindBackGround();

//change the background to 0 and the Edges to 255
this->BlacknWhite(m_bgcolor);

for(int a=0; a < m_sizeBuffered; a++)
{
BYTE ch = m_bmpBuffer[a];
m_vecPixels.push_back(ch);
ch=0;
}

this->Process_BMPdata();

}

void CBmp::Process_BMPdata()
{
if(m_width%8)
m_width = m_width + (8 - m_width%8);
else if(m_width%32)
m_width = m_width + (32-m_width%32);

// Converts and appends rows in the form of 8xn ie set of 8 bits
vecint::iterator iter = m_vecPixels.begin();

int row=0;
int col=0;

FILE *fp1;
fp1 = fopen("rastordata.txt","w");

for(iter; iter != m_vecPixels.end(); ++iter)
{
if(!InttoBoolConverter(*iter))
return;//TODO Write Error msg

if(col == (m_width))
{
col=0;
row++;
}

for(int i=0; i< 8; ++i)
{
if(m_eightblocks[i] == true)
{
printf("(X,Y)=(%d,%d)\n",row,col);

fprintf(fp1,"%d,%d\n",row,col);
if(0 == m_side) //XY plane (front)
m_vecCords.push_back(_v3f(col,m_height - row,0));
else if(1 == m_side)//XZ plane (top)
m_vecCords.push_back(_v3f(col,0,m_height - row));
else if(2 == m_side)//YZ plane (Side)
m_vecCords.push_back(_v3f(0,m_height - row,col));
}
col++;
}
}
fclose(fp1);


}

bool CBmp::InttoBoolConverter(int nData)
{
unsigned short counter = 7;
unsigned short thevalue;
thevalue = nData;
// bool boolData[8];

memset(m_eightblocks,0,8);

if(thevalue < 0)
thevalue = -1*thevalue; // converts negative to positive value

if(thevalue > 255)
{
// give msg that limit exceeds
// cout<<"\n The value exceeds\n";
// Values are set to minimum
return false;
}

// Value gets converted to boolean and gets stored
while(thevalue!=0)
{
m_eightblocks[counter]= (thevalue )& 1 ;
thevalue = thevalue >> 1;
counter--;
}

return true;
}


bool CBmp::SetSize_BMPbuffer(long size)
{
m_bmpBuffer = (BYTE*)GlobalAlloc(GPTR,size);//allocate memory for image
if(NULL == m_bmpBuffer){
MessageBox(NULL,"Memory Allocation for BMP buffer failed","",0);
return false;
}
memset(m_bmpBuffer,0,size);
return true;
}

long CBmp::GetSize_BMPimage()
{
BITMAP bmp;
::GetObject (m_hBitmap, sizeof (bmp), & bmp);
m_width = bmp.bmWidth;
m_height = bmp.bmHeight;

return (long(m_width*m_height));
}

int CBmp::FindBackGround()
{
if(NULL == m_bmpBuffer);
return -1;

float PixArray[256];
int tmp= 0,bg = 0;

for(int ii=0;ii<256;ii++)
PixArray[ii]=0;

for(int i=0;i for(int j=0;j BYTE x = m_bmpBuffer[i * m_width +j];
PixArray[x]++;
}
}

/**Finding Maximum */
for(int k=0;k<256;k++){
if(tmp tmp = (int) PixArray[k];
bg = k;
}
}
return bg;
}

/*Converting the Image buffer into black and white image*/
/* Background =0
Edge = 255 */
void CBmp::BlacknWhite(int nBGVal)
{
if(NULL == m_bmpBuffer);
return ;

for(int i=0;i {
for(int j=0;j {
if(m_bmpBuffer[i * m_width+j] == nBGVal)
m_bmpBuffer[i * m_width+j] = 0;
else
m_bmpBuffer[i * m_width+j] = 255;
//printf("The buf =%d\n",m_bmpBuffer[i * m_width+j]);
}
}
}

Classes (I)

Classes (I)

A class is an expanded concept of a data structure: instead of holding only data, it can hold both data and functions.

An object is an instantiation of a class. In terms of variables, a class would be the type, and an object would be the variable.

Classes are generally declared using the keyword class, with the following format:

class class_name {
access_specifier_1:
member1;
access_specifier_2:
member2;
...
} object_names;

Where class_name is a valid identifier for the class, object_names is an optional list of names for objects of this class. The body of the declaration can contain members, that can be either data or function declarations, and optionally access specifiers.

All is very similar to the declaration on data structures, except that we can now include also functions and members, but also this new thing called access specifier. An access specifier is one of the following three keywords: private, public or protected. These specifiers modify the access rights that the members following them acquire:

  • private members of a class are accessible only from within other members of the same class or from their friends.
  • protected members are accessible from members of their same class and from their friends, but also from members of their derived classes.
  • Finally, public members are accessible from anywhere where the object is visible.

By default, all members of a class declared with the class keyword have private access for all its members. Therefore, any member that is declared before one other class specifier automatically has private access. For example:

class CRectangle {
int x, y;
public:
void set_values (int,int);
int area (void);
} rect;

Declares a class (i.e., a type) called CRectangle and an object (i.e., a variable) of this class called rect. This class contains four members: two data members of type int (member x and member y) with private access (because private is the default access level) and two member functions with public access: set_values() and area(), of which for now we have only included their declaration, not their definition.

Notice the difference between the class name and the object name: In the previous example, CRectangle was the class name (i.e., the type), whereas rect was an object of type CRectangle. It is the same relationship int and a have in the following declaration:

int a;

where int is the type name (the class) and a is the variable name (the object).

After the previous declarations of CRectangle and rect, we can refer within the body of the program to any of the public members of the object rect as if they were normal functions or normal variables, just by putting the object's name followed by a dot (.) and then the name of the member. All very similar to what we did with plain data structures before. For example:

rect.set_values (3,4);
myarea = rect.area();

The only members of rect that we cannot access from the body of our program outside the class are x and y, since they have private access and they can only be referred from within other members of that same class.

Here is the complete example of class CRectangle:

// classes example
#include
using namespace std;

class CRectangle {
int x, y;
public:
void set_values (int,int);
int area () {return (x*y);}
};

void CRectangle::set_values (int a, int b) {
x = a;
y = b;
}

int main () {
CRectangle rect;
rect.set_values (3,4);
cout << "area: " << rect.area();
return 0;
}
area: 12

The most important new thing in this code is the operator of scope (::, two colons) included in the definition of set_values(). It is used to define a member of a class from outside the class declaration itself.

You may notice that the definition of the member function area() has been included directly within the definition of the CRectangle class given its extreme simplicity, whereas set_values() has only its prototype declared within the class, but its definition is outside it. In this outside declaration, we must use the operator of scope (::) to specify that we are defining a function that is a member of the class CRectangle and not a regular global function.

The scope operator (::) specifies the class to which the member being declared belongs, granting exactly the same scope properties as if this function definition was directly included within the class definition. For example, in the function set_values() of the previous code, we have been able to use the variables x and y, which are private members of class CRectangle, which means they are only accessible from other members of their class.

The only difference between defining a class member function completely within its class and to include only the prototype and later its definition, is that in the first case the function will automatically be considered an inline member function by the compiler, while in the second it will be a normal (not-inline) class member function, which in fact supposes no difference in behavior.

Members x and y have private access (remember that if nothing else is said, all members of a class defined with keyword class have private access). By declaring them private we deny access to them from anywhere outside the class. This makes sense, since we have already defined a member function to set values for those members within the object: the member function set_values(). Therefore, the rest of the program does not need to have direct access to them. Perhaps in a so simple example as this, it is difficult to see an utility in protecting those two variables, but in greater projects it may be very important that values cannot be modified in an unexpected way (unexpected from the point of view of the object).

One of the greater advantages of a class is that, as any other type, we can declare several objects of it. For example, following with the previous example of class CRectangle, we could have declared the object rectb in addition to the object rect:

// example: one class, two objects
#include
using namespace std;

class CRectangle {
int x, y;
public:
void set_values (int,int);
int area () {return (x*y);}
};

void CRectangle::set_values (int a, int b) {
x = a;
y = b;
}

int main () {
CRectangle rect, rectb;
rect.set_values (3,4);
rectb.set_values (5,6);
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
return 0;
}
rect area: 12
rectb area: 30

In this concrete case, the class (type of the objects) to which we are talking about is CRectangle, of which there are two instances or objects: rect and rectb. Each one of them has its own member variables and member functions.

Notice that the call to rect.area() does not give the same result as the call to rectb.area(). This is because each object of class CRectangle has its own variables x and y, as they, in some way, have also their own function members set_value() and area() that each uses its object's own variables to operate.

That is the basic concept of object-oriented programming: Data and functions are both members of the object. We no longer use sets of global variables that we pass from one function to another as parameters, but instead we handle objects that have their own data and functions embedded as members. Notice that we have not had to give any parameters in any of the calls to rect.area or rectb.area. Those member functions directly used the data members of their respective objects rect and rectb.

Constructors and destructors

Objects generally need to initialize variables or assign dynamic memory during their process of creation to become operative and to avoid returning unexpected values during their execution. For example, what would happen if in the previous example we called the member function area() before having called function set_values()? Probably we would have gotten an undetermined result since the members x and y would have never been assigned a value.

In order to avoid that, a class can include a special function called constructor, which is automatically called whenever a new object of this class is created. This constructor function must have the same name as the class, and cannot have any return type; not even void.

We are going to implement CRectangle including a constructor:

// example: class constructor
#include
using namespace std;

class CRectangle {
int width, height;
public:
CRectangle (int,int);
int area () {return (width*height);}
};

CRectangle::CRectangle (int a, int b) {
width = a;
height = b;
}

int main () {
CRectangle rect (3,4);
CRectangle rectb (5,6);
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
return 0;
}
rect area: 12
rectb area: 30

As you can see, the result of this example is identical to the previous one. But now we have removed the member function set_values(), and have included instead a constructor that performs a similar action: it initializes the values of x and y with the parameters that are passed to it.

Notice how these arguments are passed to the constructor at the moment at which the objects of this class are created:

CRectangle rect (3,4);
CRectangle rectb (5,6);

Constructors cannot be called explicitly as if they were regular member functions. They are only executed when a new object of that class is created.

You can also see how neither the constructor prototype declaration (within the class) nor the latter constructor definition include a return value; not even void.

The destructor fulfills the opposite functionality. It is automatically called when an object is destroyed, either because its scope of existence has finished (for example, if it was defined as a local object within a function and the function ends) or because it is an object dynamically assigned and it is released using the operator delete.

The destructor must have the same name as the class, but preceded with a tilde sign (~) and it must also return no value.

The use of destructors is especially suitable when an object assigns dynamic memory during its lifetime and at the moment of being destroyed we want to release the memory that the object was allocated.

// example on constructors and destructors
#include
using namespace std;

class CRectangle {
int *width, *height;
public:
CRectangle (int,int);
~CRectangle ();
int area () {return (*width * *height);}
};

CRectangle::CRectangle (int a, int b) {
width = new int;
height = new int;
*width = a;
*height = b;
}

CRectangle::~CRectangle () {
delete width;
delete height;
}

int main () {
CRectangle rect (3,4), rectb (5,6);
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
return 0;
}
rect area: 12
rectb area: 30

Overloading Constructors

Like any other function, a constructor can also be overloaded with more than one function that have the same name but different types or number of parameters. Remember that for overloaded functions the compiler will call the one whose parameters match the arguments used in the function call. In the case of constructors, which are automatically called when an object is created, the one executed is the one that matches the arguments passed on the object declaration:
// overloading class constructors
#include
using namespace std;

class CRectangle {
int width, height;
public:
CRectangle ();
CRectangle (int,int);
int area (void) {return (width*height);}
};

CRectangle::CRectangle () {
width = 5;
height = 5;
}

CRectangle::CRectangle (int a, int b) {
width = a;
height = b;
}

int main () {
CRectangle rect (3,4);
CRectangle rectb;
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
return 0;
}
rect area: 12
rectb area: 25

In this case, rectb was declared without any arguments, so it has been initialized with the constructor that has no parameters, which initializes both width and height with a value of 5.

Important: Notice how if we declare a new object and we want to use its default constructor (the one without parameters), we do not include parentheses ():

CRectangle rectb;   // right
CRectangle rectb(); // wrong!

Default constructor

If you do not declare any constructors in a class definition, the compiler assumes the class to have a default constructor with no arguments. Therefore, after declaring a class like this one:
class CExample {
public:
int a,b,c;
void multiply (int n, int m) { a=n; b=m; c=a*b; };
};

The compiler assumes that CExample has a default constructor, so you can declare objects of this class by simply declaring them without any arguments:

CExample ex;

But as soon as you declare your own constructor for a class, the compiler no longer provides an implicit default constructor. So you have to declare all objects of that class according to the constructor prototypes you defined for the class:

class CExample {
public:
int a,b,c;
CExample (int n, int m) { a=n; b=m; };
void multiply () { c=a*b; };
};

Here we have declared a constructor that takes two parameters of type int. Therefore the following object declaration would be correct:

CExample ex (2,3);
But,
CExample ex;

Would not be correct, since we have declared the class to have an explicit constructor, thus replacing the default constructor.

But the compiler not only creates a default constructor for you if you do not specify your own. It provides three special member functions in total that are implicitly declared if you do not declare your own. These are the copy constructor, the copy assignment operator, and the default destructor.

The copy constructor and the copy assignment operator copy all the data contained in another object to the data members of the current object. For CExample, the copy constructor implicitly declared by the compiler would be something similar to:

CExample::CExample (const CExample& rv) {
a=rv.a; b=rv.b; c=rv.c;
}

Therefore, the two following object declarations would be correct:

CExample ex (2,3);
CExample ex2 (ex); // copy constructor (data copied from ex)

Pointers to classes

It is perfectly valid to create pointers that point to classes. We simply have to consider that once declared, a class becomes a valid type, so we can use the class name as the type for the pointer. For example:
CRectangle * prect;

is a pointer to an object of class CRectangle.

As it happened with data structures, in order to refer directly to a member of an object pointed by a pointer we can use the arrow operator (->) of indirection. Here is an example with some possible combinations:

// pointer to classes example
#include
using namespace std;

class CRectangle {
int width, height;
public:
void set_values (int, int);
int area (void) {return (width * height);}
};

void CRectangle::set_values (int a, int b) {
width = a;
height = b;
}

int main () {
CRectangle a, *b, *c;
CRectangle * d = new CRectangle[2];
b= new CRectangle;
c= &a;
a.set_values (1,2);
b->set_values (3,4);
d->set_values (5,6);
d[1].set_values (7,8);
cout << "a area: " << a.area() << endl;
cout << "*b area: " <<>area() << endl;
cout << "*c area: " <<>area() << endl;
cout << "d[0] area: " << d[0].area() << endl;
cout << "d[1] area: " << d[1].area() << endl;
delete[] d;
delete b;
return 0;
}
a area: 2
*b area: 12
*c area: 2
d[0] area: 30
d[1] area: 56

Next you have a summary on how can you read some pointer and class operators (*, &, ., ->, [ ]) that appear in the previous example:

expressioncan be read as
*xpointed by x
&xaddress of x
x.ymember y of object x
x->ymember y of object pointed by x
(*x).ymember y of object pointed by x (equivalent to the previous one)
x[0]first object pointed by x
x[1]second object pointed by x
x[n](n+1)th object pointed by x

Be sure that you understand the logic under all of these expressions before proceeding with the next sections. If you have doubts, read again this section and/or consult the previous sections about pointers and data structures.

Classes defined with struct and union

Classes can be defined not only with keyword class, but also with keywords struct and union.

The concepts of class and data structure are so similar that both keywords (struct and class) can be used in C++ to declare classes (i.e. structs can also have function members in C++, not only data members). The only difference between both is that members of classes declared with the keyword struct have public access by default, while members of classes declared with the keyword class have private access. For all other purposes both keywords are equivalent.

The concept of unions is different from that of classes declared with struct and class, since unions only store one data member at a time, but nevertheless they are also classes and can thus also hold function members. The default access in union classes is public.

Data Structures

Data Structures
We have already learned how groups of sequential data can be used in C++. But this is somewhat restrictive, since in many occasions what we want to store are not mere sequences of elements all of the same data type, but sets of different elements with different data types.

Data structures

A data structure is a group of data elements grouped together under one name. These data elements, known as members, can have different types and different lengths. Data structures are declared in C++ using the following syntax:

struct structure_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;

where structure_name is a name for the structure type, object_name can be a set of valid identifiers for objects that have the type of this structure. Within braces { } there is a list with the data members, each one is specified with a type and a valid identifier as its name.

The first thing we have to know is that a data structure creates a new type: Once a data structure is declared, a new type with the identifier specified as structure_name is created and can be used in the rest of the program as if it was any other type. For example:

struct product {
int weight;
float price;
} ;

product apple;
product banana, melon;

We have first declared a structure type called product with two members: weight and price, each of a different fundamental type. We have then used this name of the structure type (product) to declare three objects of that type: apple, banana and melon as we would have done with any fundamental data type.

Once declared, product has become a new valid type name like the fundamental ones int, char or short and from that point on we are able to declare objects (variables) of this compound new type, like we have done with apple, banana and melon.

Right at the end of the struct declaration, and before the ending semicolon, we can use the optional field object_name to directly declare objects of the structure type. For example, we can also declare the structure objects apple, banana and melon at the moment we define the data structure type this way:

struct product {
int weight;
float price;
} apple, banana, melon;

It is important to clearly differentiate between what is the structure type name, and what is an object (variable) that has this structure type. We can instantiate many objects (i.e. variables, like apple, banana and melon) from a single structure type (product).

Once we have declared our three objects of a determined structure type (apple, banana and melon) we can operate directly with their members. To do that we use a dot (.) inserted between the object name and the member name. For example, we could operate with any of these elements as if they were standard variables of their respective types:

apple.weight
apple.price
banana.weight
banana.price
melon.weight
melon.price

Each one of these has the data type corresponding to the member they refer to: apple.weight, banana.weight and melon.weight are of type int, while apple.price, banana.price and melon.price are of type float.

Let's see a real example where you can see how a structure type can be used in the same way as fundamental types:

// example about structures
#include
#include
#include
using namespace std;

struct movies_t {
string title;
int year;
} mine, yours;

void printmovie (movies_t movie);

int main ()
{
string mystr;

mine.title = "2001 A Space Odyssey";
mine.year = 1968;

cout << "Enter title: ";
getline (cin,yours.title);
cout << "Enter year: ";
getline (cin,mystr);
stringstream(mystr) >> yours.year;

cout << "My favorite movie is:\n ";
printmovie (mine);
cout << "And yours is:\n ";
printmovie (yours);
return 0;
}

void printmovie (movies_t movie)
{
cout << movie.title;
cout << " (" << class="str">")\n";
}
Enter title: Alien
Enter year: 1979

My favorite movie is:
2001 A Space Odyssey (1968)
And yours is:
Alien (1979)

The example shows how we can use the members of an object as regular variables. For example, the member yours.year is a valid variable of type int, and mine.title is a valid variable of type string.

The objects mine and yours can also be treated as valid variables of type movies_t, for example we have passed them to the function printmovie as we would have done with regular variables. Therefore, one of the most important advantages of data structures is that we can either refer to their members individually or to the entire structure as a block with only one identifier.

Data structures are a feature that can be used to represent databases, especially if we consider the possibility of building arrays of them:

// array of structures
#include
#include
#include
using namespace std;

#define N_MOVIES 3

struct movies_t {
string title;
int year;
} films [N_MOVIES];

void printmovie (movies_t movie);

int main ()
{
string mystr;
int n;

for (n=0; n {
cout << "Enter title: ";
getline (cin,films[n].title);
cout << "Enter year: ";
getline (cin,mystr);
stringstream(mystr) >> films[n].year;
}

cout << "\nYou have entered these movies:\n";
for (n=0; n printmovie (films[n]);
return 0;
}

void printmovie (movies_t movie)
{
cout << movie.title;
cout << " (" << class="str">")\n";
}
Enter title: Blade Runner
Enter year: 1982
Enter title: Matrix
Enter year: 1999
Enter title: Taxi Driver
Enter year: 1976

You have entered these movies:
Blade Runner (1982)
Matrix (1999)
Taxi Driver (1976)

Pointers to structures

Like any other type, structures can be pointed by its own type of pointers:
struct movies_t {
string title;
int year;
};

movies_t amovie;
movies_t * pmovie;

Here amovie is an object of structure type movies_t, and pmovie is a pointer to point to objects of structure type movies_t. So, the following code would also be valid:

pmovie = &amovie;

The value of the pointer pmovie would be assigned to a reference to the object amovie (its memory address).

We will now go with another example that includes pointers, which will serve to introduce a new operator: the arrow operator (->):

// pointers to structures
#include
#include
#include
using namespace std;

struct movies_t {
string title;
int year;
};

int main ()
{
string mystr;

movies_t amovie;
movies_t * pmovie;
pmovie = &amovie;

cout << "Enter title: ";
getline (cin, pmovie->title);
cout << "Enter year: ";
getline (cin, mystr);
(stringstream) mystr >> pmovie->year;

cout << "\nYou have entered:\n";
cout <<>title;
cout << " (" <<>year << ")\n";

return 0;
}
Enter title: Invasion of the body snatchers
Enter year: 1978

You have entered:
Invasion of the body snatchers (1978)

The previous code includes an important introduction: the arrow operator (->). This is a dereference operator that is used exclusively with pointers to objects with members. This operator serves to access a member of an object to which we have a reference. In the example we used:

pmovie->title

Which is for all purposes equivalent to:

(*pmovie).title

Both expressions pmovie->title and (*pmovie).title are valid and both mean that we are evaluating the member title of the data structure pointed by a pointer called pmovie. It must be clearly differentiated from:

*pmovie.title

which is equivalent to:

*(pmovie.title)

And that would access the value pointed by a hypothetical pointer member called title of the structure object pmovie (which in this case would not be a pointer). The following panel summarizes possible combinations of pointers and structure members:

ExpressionWhat is evaluatedEquivalent
a.bMember b of object a
a->bMember b of object pointed by a(*a).b
*a.bValue pointed by member b of object a*(a.b)

Nesting structures

Structures can also be nested so that a valid element of a structure can also be on its turn another structure.

struct movies_t {
string title;
int year;
};

struct friends_t {
string name;
string email;
movies_t favorite_movie;
} charlie, maria;

friends_t * pfriends = &charlie;

After the previous declaration we could use any of the following expressions:

charlie.name
maria.favorite_movie.title
charlie.favorite_movie.year
pfriends->favorite_movie.year
(where, by the way, the last two expressions refer to the same member).

Dynamic Memory

Dynamic Memory

Until now, in all our programs, we have only had as much memory available as we declared for our variables, having the size of all of them to be determined in the source code, before the execution of the program. But, what if we need a variable amount of memory that can only be determined during runtime? For example, in the case that we need some user input to determine the necessary amount of memory space.

The answer is dynamic memory, for which C++ integrates the operators new and delete.

Operators new and new[]

In order to request dynamic memory we use the operator new. new is followed by a data type specifier and -if a sequence of more than one element is required- the number of these within brackets []. It returns a pointer to the beginning of the new block of memory allocated. Its form is:

pointer = new type
pointer = new type [number_of_elements]

The first expression is used to allocate memory to contain one single element of type type. The second one is used to assign a block (an array) of elements of type type, where number_of_elements is an integer value representing the amount of these. For example:

int * bobby;
bobby = new int [5];

In this case, the system dynamically assigns space for five elements of type int and returns a pointer to the first element of the sequence, which is assigned to bobby. Therefore, now, bobby points to a valid block of memory with space for five elements of type int.

The first element pointed by bobby can be accessed either with the expression bobby[0] or the expression *bobby. Both are equivalent as has been explained in the section about pointers. The second element can be accessed either with bobby[1] or *(bobby+1) and so on...

You could be wondering the difference between declaring a normal array and assigning dynamic memory to a pointer, as we have just done. The most important difference is that the size of an array has to be a constant value, which limits its size to what we decide at the moment of designing the program, before its execution, whereas the dynamic memory allocation allows us to assign memory during the execution of the program (runtime) using any variable or constant value as its size.

The dynamic memory requested by our program is allocated by the system from the memory heap. However, computer memory is a limited resource, and it can be exhausted. Therefore, it is important to have some mechanism to check if our request to allocate memory was successful or not.

C++ provides two standard methods to check if the allocation was successful:

One is by handling exceptions. Using this method an exception of type bad_alloc is thrown when the allocation fails. Exceptions are a powerful C++ feature explained later in these tutorials. But for now you should know that if this exception is thrown and it is not handled by a specific handler, the program execution is terminated.

This exception method is the default method used by new, and is the one used in a declaration like:

bobby = new int [5];  // if it fails an exception is thrown 

The other method is known as nothrow, and what happens when it is used is that when a memory allocation fails, instead of throwing a bad_alloc exception or terminating the program, the pointer returned by new is a null pointer, and the program continues its execution.

This method can be specified by using a special object called nothrow as parameter for new:

bobby = new (nothrow) int [5];

In this case, if the allocation of this block of memory failed, the failure could be detected by checking if bobby took a null pointer value:

int * bobby;
bobby = new (nothrow) int [5];
if (bobby == 0) {
// error assigning memory. Take measures.
};

This nothrow method requires more work than the exception method, since the value returned has to be checked after each and every memory allocation, but I will use it in our examples due to its simplicity. Anyway this method can become tedious for larger projects, where the exception method is generally preferred. The exception method will be explained in detail later in this tutorial.

Operator delete and delete[]

Since the necessity of dynamic memory is usually limited to specific moments within a program, once it is no longer needed it should be freed so that the memory becomes available again for other requests of dynamic memory. This is the purpose of the operator delete, whose format is:
delete pointer;
delete [] pointer;

The first expression should be used to delete memory allocated for a single element, and the second one for memory allocated for arrays of elements.

The value passed as argument to delete must be either a pointer to a memory block previously allocated with new, or a null pointer (in the case of a null pointer, delete produces no effect).

// rememb-o-matic
#include
using namespace std;

int main ()
{
int i,n;
int * p;
cout << "How many numbers would you like to type? ";
cin >> i;
p= new (nothrow) int[i];
if (p == 0)
cout << "Error: memory could not be allocated";
else
{
for (n=0; n < i; n++ )
{
cout < < span class="str">"Enter number: ";
cin >> p[n];
}
cout << span class="str">"You have entered: ";
for( n=0; n cout << class="str">", ";
delete[] p;
}
return 0;
}
How many numbers would you like to type? 5
Enter number : 75
Enter number : 436
Enter number : 1067
Enter number : 8
Enter number : 32
You have entered: 75, 436, 1067, 8, 32,

Notice how the value within brackets in the new statement is a variable value entered by the user (i), not a constant value:

p= new (nothrow) int[i];

But the user could have entered a value for i so big that our system could not handle it. For example, when I tried to give a value of 1 billion to the "How many numbers" question, my system could not allocate that much memory for the program and I got the text message we prepared for this case (Error: memory could not be allocated). Remember that in the case that we tried to allocate the memory without specifying the nothrow parameter in the new expression, an exception would be thrown, which if it's not handled terminates the program.

It is a good practice to always check if a dynamic memory block was successfully allocated. Therefore, if you use the nothrow method, you should always check the value of the pointer returned. Otherwise, use the exception method, even if you do not handle the exception. This way, the program will terminate at that point without causing the unexpected results of continuing executing a code that assumes a block of memory to have been allocated when in fact it has not.

Dynamic memory in ANSI-C

Operators new and delete are exclusive of C++. They are not available in the C language. But using pure C language, dynamic memory can also be used through the functions malloc, calloc, realloc and free, defined in the header file, and since C++ is a superset of C, these functions are also available to C++ programmers (see cstdlib for more info).

The memory blocks allocated by these functions are not necessarily compatible with those returned by new, so each one should be manipulated with its own set of functions or operators.