|
Related YoLinux Tutorials:
°Linux and C++
°C++ Unions & Structures
°C++ Enumerations
°C++ STL
°C++ STL Map
°C++ String Class
°C++ Singleton
°C++ Coding Style
°C++ XML Beans
°C++ Memory Corruption
°C/C++ Signal Handling
°C++ CGI
°Fork and exec with C/C++
°CORBA (OmniORB) with C++
°Emacs and C/C++
°Advanced VI
°YoLinux Tutorials Index
Free Information Technology Magazines and Document Downloads
Free Information Technology Software and Development Magazine Subscriptions and Document Downloads
|
| C malloc and free vs C++ new and delete: |
C malloc() and free() do not call constructors or destructors.
C++ new and delete operators are "class aware" and will call class constructors when a class is allocated with new and a destructor when delete is called. [example]
Mixing malloc with delete or new with free is undefined.
In addition, C++ new and delete
operators were introduced with the C++ practice of allocating memory in
constructors and deallocating the same memory with a destructor.
new/delete advantages:
- new/delete invokes constructor/destructor. Malloc/free will not.
- new does not need typcasting. Malloc requires typcasting the returned pointer.
- new/delete operators can be overloaded, malloc/free can not.
- new does not require you to explicitly calculate the quantity of memory required. (Unlike malloc)
| C dynamic memory allocation: |
Use "malloc", "calloc" and "free": File: MallocTest.cpp
-
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <error.h>
typedef struct
{
int ii;
double dd;
} SSS;
int main()
{
int kk, jj;
char *str1="This is a text string";
char *str2 = malloc(strlen(str1));
SSS *s1 = calloc(4, sizeof(SSS));
if(s1 == ENOMEM) printf("Error ENOMEM: Insufficient memory available\n");
strcpy(str2,str1); /* Make a copy of the string */
for(kk=0; kk < 5; kk++)
{
s1[kk].ii=kk;
}
for(jj=0; jj < 5; jj++)
{
printf("Value strored: %d\n",s1[jj].ii);
}
free(s1);
free(str2);
}
|
Compile: gcc -o MallocTest MallocTest.cpp
Run: MallocTest
Value strored: 0
Value strored: 1
Value strored: 2
Value strored: 3
Value strored: 4
|
Manual pages:
- malloc: a memory allocator
- calloc: a memory allocator
- realloc: memory reallocator
- free: frees the memory space pointed to by ptr
| C++ dynamic memory allocation: |
Use "new" and "delete": File: AllocNewTest.cpp
-
#include <iostream>
class CCC
{
public:
CCC(){};
CCC(int);
CCC(int, double);
int ii;
double dd;
};
CCC::CCC(int _ii)
: ii(_ii)
{
};
CCC::CCC(int _ii, double _dd)
: ii(_ii), dd(_dd)
{
};
using namespace std;
main()
{
CCC *cc1 = new CCC(4, 5.5); // Pointer. Contructor called.
CCC *cc2 = new CCC[5]; // Pointer to an array of objects.
CCC &cc3 = *new CCC; // Reference
cc1->ii=5;
cc2[3].ii=6;
cc3.ii=7;
cout << cc1->ii << endl;
cout << cc2[3].ii << endl;
cout << cc3.ii << endl;
delete cc1;
delete [] cc2;
delete & cc3;
}
|
Note the difference between:
| C function returning a pointer vs C++ function returning a copy: |
-
C function returning a pointer:
#include <stdio.h>
#include <stdlib.h>
char *fnConvert(int _ii)
{
char *str = malloc(10); /* Return 10 character string */
if(str == NULL)
fprintf(stderr,"Error: Memory allocation failed.\n");
sprintf(str, "%d", _ii);
return str;
}
main()
{
char *s1=fnConvert( 34567 );
printf("%s\n", s1);
free(s1);
}
|
C++ function returning a copy:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
string fnConvert(int _ii)
{
ostringstream ost;
ost << _ii;
return ost.str();
}
main()
{
cout << fnConvert( 34567 ) << endl;
}
|
Note: The STL string class copy constructor is employed to return a
copy (return by value). Yes the variable "ost" is out of scope once we
leave the function, but the copy of its contents is valid.
Do not "return ost.str().c_str()" as this pointer is out of scope once
the procesing leaves the function and the data lost.
| C++ dynamic memory allocation exception handling: |
Use exception handling:
-
#include <iostream>
using namespace std;
main()
{
int ii;
double *ptr[5000000];
try
{
for( ii=0; ii < 5000000; ii++)
{
ptr[ii] = new double[5000000];
}
}
catch ( bad_alloc &memmoryAllocationException )
{
cout << "Error on loop number: " << ii << endl;
cout << "Memory allocation exception occurred: "
<< memmoryAllocationException.what()
<< endl;
}
catch(...)
}
cout << "Unrecognized exception" << endl;
{
}
|
Compile: g++ -o AllocNewTest AllocNewTest.cpp
Run:
- Observer system limits: ulimit -a
- Set system limits: ulimit -m 100
- Run with fewer privileges: nice -n 19 AllocNewTest
Using polymorphism to delete dynamically allocated objects by
their base class pointer: Declare base class destructor virtual so that
the delete operator can be applied to the base class pointer. The
derived class destructor is called first, before the base class
destructor.
-
#include <iostream>
using namespace std;
class Base
{
public:
Base(){};
virtual ~Base(){ cout << "Base class destructor called" << endl; }
};
class Derived : public Base
{
public:
Derived(){};
~Derived(){ cout << "Derived class destructor called" << endl; }
};
main()
{
Base *ptr = new Derived();
delete ptr;
}
|
Resutls:
Derived class destructor called
Base class destructor called
Note:
- If the delete operator is applied to the base class and the
destructor is NOT virtual, then this will cause a memory leak as only a
portion of the memory is freed.
- Base class destructor is not pure virtual (set =0) or there would be no base class implementation of the destructor..
- Class contructors can NOT be virtual.
Books: |
-
|
|