Showing posts with label Memory Allocation. Show all posts
Showing posts with label Memory Allocation. Show all posts

Wednesday, 27 October 2010

'new operator' throw and nothrow

I used to always think and while coding take care that to check if memory allocation is successful, we need to check if the returned pointer is not NULL. Well, in MSVC8 this may not necessarily be true. Depending on the library you include (see here) you may end up with either a throw or a NULL. The partial good news is that you can in future write your code to not throw memory alloc failure. See example:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

try

{

char
* p = new char[0x7fffffff];
if
(!p)
{

cout<<"Memory allocation for q failed. NULL returned."<<endl;
}
}

catch
(...)
{

cout<<"Exception caught by ..."<<endl;
}


char
* q = new (std::nothrow) char[0x7fffffff];
if
(!q)
{

cout<<"Memory allocation for q failed. NULL returned."<<endl;
}


return
0;
}




The output is as follows:

Wednesday, 20 October 2010

Memory Allocation for char*

One common problem that I have noticed is that people copy char* pointers thinking that the pointers will be valid when used but this is rarely the case. See the example below.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example demonstrates allocation of memory for char*
#include<iostream>

using namespace
std;

typedef struct
{
char
const * name;
}
TypeInfo;

TypeInfo* MakeType(const char *typeName)
{

TypeInfo* newNamedTypeInfo = new TypeInfo;

char
* newTypeName = new char[strlen(typeName) + 1];
strcpy(newTypeName, typeName);
newNamedTypeInfo->name = newTypeName;

return
newNamedTypeInfo;
}


int
main()
{

TypeInfo* testType = MakeType("Apple Banana");
cout << "testType->name = " << testType->name << endl;

return
0;
}





Please suggest any improvements.

The output is as follows:
Note that there is a memory leak in the program if you can spot it and fix it then you are already half way through :)

Wednesday, 27 January 2010

Memory Allocation example for Double Pointer of a class

The following program should be self explanatory:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to demonstrate memory allocation to double pointers
#include<iostream>

using namespace
std;

//Class named NewClass
class NewClass
{

public
:
int
a;
int
* b;
void
* c;
};


//List Structure containing multiple NewClass objects
struct NewClassList
{

int
numOfObjects;
NewClass** Objects;
};


int
main()
{

//Create NewClassList with 4 objects with following values:
//1, 10, 100; 2, 20; 200; 3, 30, 300; 4, 40, 400;
NewClassList someList;
someList.numOfObjects = 4;
//someList.Objects = new NewClass*; //1. Common mistake in allocating memory
someList.Objects = new NewClass*[someList.numOfObjects];

someList.Objects[0] = new NewClass;
someList.Objects[0]->a = 1;
someList.Objects[0]->b = new int(10);
someList.Objects[0]->c = (void*) new int(100);

someList.Objects[1] = new NewClass;
someList.Objects[1]->a = 2;
someList.Objects[1]->b = new int(20);
someList.Objects[1]->c = (void*) new int(200);

someList.Objects[2] = new NewClass;
someList.Objects[2]->a = 3;
someList.Objects[2]->b = new int(30);
someList.Objects[2]->c = (void*) new int(300);

someList.Objects[3] = new NewClass;
someList.Objects[3]->a = 4;
someList.Objects[3]->b = new int(40);
someList.Objects[3]->c = (void*) new int(400);

//Printing the outputs
for(int i = 0; i < someList.numOfObjects; i++)
{

cout<<"Iteration = "<<i;
cout<<": a = "<<someList.Objects[i]->a;
cout<<": b = "<<*(someList.Objects[i]->b);
cout<<": c = "<<*((int*)someList.Objects[i]->c)<<endl;
}


//Clear all the memory allocation
for(int i = 0; i < someList.numOfObjects; i++)
{

delete
someList.Objects[i]->b;
delete
someList.Objects[i]->c;
delete
someList.Objects[i];
}

delete
[] someList.Objects;
return
0;
}





The output is as follows:

Wednesday, 21 October 2009

The challenging 'Infinite loop' problem

Picked this one up from The C++ blog.

Consider the following program:



#include <iostream>

int
main()
{

int
i;
int
array[4];
for
(i=0; i<=8; i++)
{

array[i]=0;
}


return
0;
}


Most people including myself expect this program to crash. This is not the case. The reason being the way everything is stored on stack. In simple representation, the storage is something like this:



So when i = 6, value of i is reset to 0 and the loop continues forever.

After digging some information on stack, heap, etc. I found some useful info in C++ in 24 hours:

Programmers generally deal with five areas of memory:
  • Global name space
  • The free store (a.k.a. Heap)
  • Registers
  • Code space
  • The stack

Local variables are on the stack, along with function parameters. Code is in code space, of course, and global variables are in global name space. The registers are used for internal housekeeping functions, such as keeping track of the top of the stack and the instruction pointer. Just about all remaining memory is given over to the free store, which is sometimes referred to as the heap.

The problem with local variables is that they don't persist. When the function returns, the local variables are thrown away. Global variables solve that problem at the cost of unrestricted access throughout the program, which leads to the creation of code that is difficult to understand and maintain. Putting data in the free store solves both of these problems.

You can think of the free store as a massive section of memory in which thousands of sequentially numbered cubbyholes lie waiting for your data. You can't label these cubbyholes, though, as you can with the stack. You must ask for the address of the cubbyhole that you reserve and then stash that address away in a pointer.

The stack is cleaned automatically when a function returns. All the local variables go out of scope, and they are removed from the stack. The free store is not cleaned until your program ends, and it is your responsibility to free any memory that you've reserved when you are done with it.

The advantage to the free store is that the memory you reserve remains available until you explicitly free it. If you reserve memory on the free store while in a function, the memory is still available when the function returns.

The advantage of accessing memory in this way, rather than using global variables, is that only functions with access to the pointer have access to the data. This provides a tightly controlled interface to that data, and it eliminates the problem of one function changing that data in unexpected and unanticipated ways.

For this to work, you must be able to create a pointer to an area on the free store and to pass that pointer among functions. The pointer is created using new and once you are done with it you can free the memory using delete.

Wednesday, 17 June 2009

Initialising Arrays while doing 'new'

The example below shows how to initialise the array when you are dynamically alocating the memory with new:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

//int* x = new int(10); - Common Bug for Array allocation
int *x = new int[5]; // Memory UnInitialised
int *y = new int[5]();

for
(int i = 0; i < 5; i++)
{

cout<<"x["<<i<<"]="<<x[0]<<endl;
cout<<"y["<<i<<"]="<<y[0]<<endl;
}


//delete x; - Another Common bug
delete[] x;
delete
[] y;
return
0;
}



The output is as follows: