Wednesday, January 6, 2010

new & delete in C/C++

new :
void* operator new (std::size_t size) throw (std::bad_alloc);
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
Allocate storage space

The first version allocates size bytes of storage space, aligned to represent an object of that size, and returns a non-null pointer to the first byte of this block. On failure, it throws a bad_alloc exception.

The second version is the nothrow version. It does the same as the first version, except that on failure it returns a null pointer instead of throwing an exception.

operator new are declared in the global namespace, not in the std namespace.
The first and second versions are implicitly declared in every translation unit of a C++ program: The header does not need to be included for them to be present.

operator new can be called explicitly as a regular function, but in C++, new is an operator with a very specific behavior: An expression with the new operator, first calls function operator new with the size of its type specifier as first argument, and if this is successful, it then automatically initializes or constructs the object (if needed). Finally, the expression evaluates as a pointer to the appropriate type.


delete :
void operator delete (void* ptr) throw ();
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) throw();
Deallocate storage space

The first and second versions deallocate the memory block pointed by ptr (if not-null), releasing the storage space previously allocated to it by a call to operator new and making that pointer location invalid.

The second and third versions cannot be implicitly called by the operator expression (the delete operator calls once the function operator delete for each of its arguments). Although they can be called explicitly as operator new function calls, their default definitions serve no particular purpose - they are provided as counterparts for the operator new functions and called accordingly when done automatically.

operator delete can be called explicitly as a regular function, but in C++, delete is an operator with a very specific behavior: An expression with the delete operator, first calls the appropriate destructor (if needed), and then calls function operator delete to release the storage.

// operator delete example
#include < iostream >
#include < new >
using namespace std;

struct myclass {
myclass() {cout <<"myclass constructed\n";} ~myclass() {cout <<"myclass destroyed\n";} }; int main () { myclass * pt; pt = new myclass; delete pt; return 0; } Output: myclass constructed myclass destroyed Example of a new: #include < iostream >
#include < new >
using namespace std;

struct myclass {myclass() {cout <<"myclass constructed\n";}};

int main () {

int * p1 = new int;
// same as:
// int * p1 = (int*) operator new (sizeof(int));

int * p2 = new (nothrow) int;
// same as:
// int * p2 = (int*) operator new (sizeof(int),nothrow);

myclass * p3 = (myclass*) operator new (sizeof(myclass));
// (!) not the same as:
// myclass * p3 = new myclass;
// (constructor not called by function call, even for non-POD types)

new (p3) myclass; // calls constructor
// same as:
// operator new (sizeof(myclass),p3)

return 0;
}

Output: myclass constructed

malloc,calloc,realloc and free

malloc(),calloc(),realloc() & free():

malloc (memory allocation) is used to dynamically allocate memory at run time. Possible uses for this function are:
Read records of an unknown length.
Read an unknown number of database records.
Link lists.
The simplest way to reserve memory is to code something like:

main()
{
char string[1000];

strcpy (string, "Some text");
}
The example above has two problems:

If the data is less than 1000 bytes we are wasting memory.
If the data is greater than 1000 bytes the program is going to crash.
The 1000 bytes are reserved throught out the life of the program. If this was a long running program that rarely used the memory, it would again be wasteful.
malloc allows us to allocate exactly the correct amount of memory and with the use of free only for the time it is required.

Library: stdlib.h

Prototype: void *malloc(size_t size);

Syntax: char * String;

String = (char *) malloc(1000);
Looking at the example syntax above, 1000 bytes are reserved and the pointer String points to the first byte. The 1000 bytes are NOT initialized by malloc. If the memory is NOT available, a NULL pointer is returned.

The calloc() Function
The standard C library declares the function calloc() in as follows:

void *calloc(size_t elements, size_t sz);
calloc() allocates space for an array of elements, each of which occupies sz bytes of storage. The space of each element is initialized to binary zeros. In other words, calloc() is similar to malloc(), except that it handles arrays of objects rather than a single chunk of storage and that it initializes the storage allocated. The following example allocates an array of 100 int's using calloc():


int * p = (int*) calloc (100, sizeof(int));
Remember that in C++, you have better alternatives to calloc() and malloc(), namely new and new [], and that these C functions should only be used for allocating POD (Plain Old Data) objects; never class objects. However, if you're using C or maintaining legacy C code, you might get across this function.

realloc:
void * realloc ( void * ptr, size_t size );
Reallocate memory block

The size of the memory block pointed to by the ptr parameter is changed to the size bytes, expanding or reducing the amount of memory available in the block.

The function may move the memory block to a new location, in which case the new location is returned. The content of the memory block is preserved up to the lesser of the new and old sizes, even if the block is moved. If the new size is larger, the value of the newly allocated portion is indeterminate.

In case that ptr is NULL, the function behaves exactly as malloc, assigning a new block of size bytes and returning a pointer to the beginning of it.

In case that the size is 0, the memory previously allocated in ptr is deallocated as if a call to free was made, and a NULL pointer is returned.

Return Value:A pointer to the reallocated memory block, which may be either the same as the ptr argument or a new location.
The type of this pointer is void*, which can be cast to the desired type of data pointer in order to be dereferenceable.
If the function failed to allocate the requested block of memory, a NULL pointer is returned.


/* realloc example: rememb-o-matic */
#include < stdio.h >
#include < stdlib.h >

int main ()
{
int input,n;
int count=0;
int * numbers = NULL;

do {
printf ("Enter an integer value (0 to end): ");
scanf ("%d", &input);
count++;
numbers = (int*) realloc (numbers, count * sizeof(int));
if (numbers==NULL)
{ puts ("Error (re)allocating memory"); exit (1); }
numbers[count-1]=input;
} while (input!=0);

printf ("Numbers entered: ");
for ( n=0; n < count; n++) printf ("%d ",numbers[n]); free (numbers); return 0; } The program prompts the user for numbers until a zero character is entered. Each time a new value is introduced the memory block pointed by numbers is increased by the size of an int. free:
Example
/* free example */
#include
#include

int main ()
{
int * buffer1, * buffer2, * buffer3;
buffer1 = (int*) malloc (100*sizeof(int));
buffer2 = (int*) calloc (100,sizeof(int));
buffer3 = (int*) realloc (buffer2,500*sizeof(int));
free (buffer1);
free (buffer3);
return 0;
}


This program has no output. Just demonstrates some ways to allocate and free dynamic memory using the cstdlib functions.

Also, check out Free ISTQB Training Material here

www.testing4success.com - Application QA/Testing     Mobile App QA/Testing     Web Testing     Training
Iphone App QA  Android App QA  Web QA 

Avoid Using malloc() and free() in C++

Avoid Using malloc() and free() in C++
The use of malloc() and free() functions in a C++ file is not recommended and is even dangerous:
1. malloc() requires the exact number of bytes as an argument whereas new calculates the size of the allocated object automatically. By using new, silly mistakes such as the following are avoided:


long * p = malloc(sizeof(short)); //p originally pointed to a short;
//changed later (but malloc's arg was not)
2. malloc() does not handle allocation failures, so you have to test the return value of malloc() on each and every call. This tedious and dangerous function imposes performance penalty and bloats your .exe files. On the other hand, new throws an exception of type std::bad_alloc when it fails, so your code may contain only one catch(std::bad_alloc) clause to handle such exceptions.

3. As opposed to new, malloc() does not invoke the object's constructor. It only allocates uninitialized memory. The use of objects allocated this way is undefined and should never occur. Similarly, free() does not invoke its object's destructor.

itoa & atoi - C/C++

itoa & atoi - C/C++

itoa:
char * itoa ( int value, char * str, int base );
Convert integer to string (non-standard function)

Converts an integer value to a null-terminated string using the specified base and stores the result in the array given by str parameter.

If base is 10 and value is negative, the resulting string is preceded with a minus sign (-). With any other base, value is always considered unsigned.

Return Value:A pointer to the resulting null-terminated string, same as parameter str.

This function is not defined in ANSI-C and is not part of C++, but is supported by some compilers.

A standard-compliant alternative for some cases may be sprintf:
sprintf(str,"%d",value) converts to decimal base.
sprintf(str,"%x",value) converts to hexadecimal base.
sprintf(str,"%o",value) converts to octal base.


/* itoa example */
#include < stdio.h >
#include < stdlib.h >

int main ()
{
int i;
char buffer [33];
printf ("Enter a number: ");
scanf ("%d",&i);
itoa (i,buffer,10);
printf ("decimal: %s\n",buffer);
itoa (i,buffer,16);
printf ("hexadecimal: %s\n",buffer);
itoa (i,buffer,2);
printf ("binary: %s\n",buffer);
return 0;
}

Output:
Enter a number: 1750
decimal: 1750
hexadecimal: 6d6
binary: 11011010110


atoi:

int atoi ( const char * str );
Convert string to integer

Parses the C string str interpreting its content as an integral number, which is returned as an int value.

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

Return Value-On success, the function returns the converted integral number as an int value.
If no valid conversion could be performed, a zero value is returned.

/* atoi example */
#include < stdio.h >
#include < stdlib.h >

int main ()
{
int i;
char szInput [256];
printf ("Enter a number: ");
fgets ( szInput, 256, stdin );
i = atoi (szInput);
printf ("The value entered is %d. The double is %d.\n",i,i*2);
return 0;
}

Output:

Enter a number: 73
The value entered is 73. The double is 146.


Also, check out Free ISTQB Training Material here

www.testing4success.com - Application QA/Testing     Mobile App QA/Testing     Web Testing     Training
Iphone App QA  Android App QA  Web QA 

Strlen() Vs sizeof()

strlen Vs sizeof

char mystr[100]="test string";

defines an array of characters with a size of 100 chars, but the C string with which mystr has been initialized has a length of only 11 characters. Therefore, while sizeof(mystr) evaluates to 100, strlen(mystr) returns 11.

/* strlen example */
#include
#include

int main ()
{
char szInput[256];
printf ("Enter a sentence: ");
gets (szInput);
printf ("The sentence entered is %u characters long.\n",strlen(szInput));
return 0;
}

Output:

Enter sentence: just testing
The sentence entered is 12 characters long.

Reverse a string C/C++

#include < iostream >
#include < string >

using namespace std;

void reverseStr(string& x)
{
string temp = "";

int len = x.length();

for(int i = len - 1; i >= 0; --i)
{
temp += x[i];
}

x = temp;
}

int main()
{
string x = "Hello World!";

cout << "x = " << x << endl;

reverseStr(x);

cout << "x = " << x << endl;

return 0;
}

Second Largest Number in An Array

#include
int main(void) {
int pri, sec, i, v;
int arr[] = {4,10,3,8,6,7,2,7,9,2,0};
pri = sec = 0;
for (i = 0; arr[i]; ++i) {
v = arr[i];
if (v > pri)
{
sec = pri;
pri = v;
}
else if ((v > sec && v < pri)||(pri == sec))
sec = v;
}
printf("pri is %d, sec is %d\n", pri, sec);
return 0;
}