C++: Why new to be used only when unavoidable?

Those who program with modern languages like C# or Java has a tendency to use each and every object declaration in C++ with new. Why we should avoid using new as much as possible?

  • Unlike Java/C#, C++ doesn’t employ any memory manager by its own to control the life time of dynamically allocated objects (using new).
  • C++ using operating system routines to allocate the memory and too much new/delete could fragment the available memory. The architecture and management of a garbage collector is entirely different from a native perspective.
  • Improper memory management could lead memory leaks and it’s really hard to track.
  • The stack objects implementation is foolproof.
  • With any application, if large chunk of memory is frequently being used, it’s advised to pre-allocate it and release when not required.
  • The downside of using stack objects are, it creates intermediate copies of objects on returning, passing to functions (by value) etc. But the memory management of C#/Java helps the (JIT)compiler to manage these tasks memory efficient. However modern C++ compilers are well aware of these situations and they’ve optimized for performance.
  • It’s really tedious in C++ if the memory being allocated and released in two different places. The responsibility for release is always a question and mostly we rely on some commonly accessible pointers, stack objects (maximum possible) and techniques like auto_ptr, shared_ptr (reference counted pointers – C++0x) (RAII objects)
  • The best thing in C++ is that, you’ve control over the memory and the worst thing is that you will not have any control over the memory if we employ an improper memory management for the application. The crashes caused due to memory corruptions are the nastiest one in the world.
In C++, the STL containers mostly rely on dynamically memory. In a way or other, they’re RAII objects, which automatically releases the resources upon destruction. In addition to that, it eases the programmers life by providing useful interfaces (services) to make best of OOP, (like operator+= with string objects, push_back function with containers, easy copying of containers by assignment etc.). It’s a good practice to make best use of the proven library classes/functions/algorithms to make your program work efficient. Also operating system memory routines are costly to handle. Hence there will beĀ  a performance hit on using dynamic memory allocation.
Of course we can’t say a stack object is completely allocated in stack to improve the performance. Consider the example of std::string class which holds the actual string content in the heap memory but the advantage is that, the memory is automatically managed on reassigning, concatenation, destruction etc.
But there are situations where we’ve to use the dynamic memory allocations like readingĀ  bytes from files where we don’t know the size of the buffer which we required to pass the read function. In such situations, either we’ve to use the dynamic memory and handle the it our self or, use the proven classes like ofstream/ifstream etc with required objects (like std::string) to read the content and thus let them manage the memory automatically.
See further on my answer in StackOverflow.com

WinDBG – Visualizing STL containers and strings

With the help of STL extension, this extension can’t visualize each and every containers or classes in STL, rather it displays the mostly used string, wstring, vector<[w]string>, list<[w]string>

for more information give !stl -? in WinDBG input or check in the help file.
See the example below and the output in the debugger console.

// SampleSTL.cpp : Defines the entry point for the console application.
// Compiled with Microsoft Visual C++ 9.0 compiler

#include "stdafx.h"
#include 
#include 
#include

#include 

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

	string str1("Quick");
	string str2("Brown" );

	string str3 = str1 + " " + str2;

	vector vec;

	vec.push_back(str1);
	vec.push_back(str2);
	vec.push_back(str3);

	list lst;

	lst.push_back( str1 );
	lst.push_back( str2 );
	lst.push_back( str3 );

	for( vector::iterator iter = vec.begin(); iter != vec.end(); ++iter)
		cout << (*iter).c_str() << endl;

	cout <::iterator iter = lst.begin(); iter != lst.end(); ++iter)
		cout << (*iter).c_str() << endl;

	return 0;
}

WinDGB output

0:000> !stl str1
[da 0x16fb18]
0016fb18  "Quick"

0:000> !stl str2
[da 0x16faf0]
0016faf0  "Brown"

0:000> !stl str3
[da 0x16fac8]
0016fac8  "Quick Brown"

0:000> !stl vec
	Element 0
[da 0x558358]
00558358  "Quick"
	Element 1
[da 0x558378]
00558378  "Brown"
	Element 2
[da 0x558398]
00558398  "Quick Brown"

0:000> !stl lst
The list has 00000003 elements
	Element 0
[da 0x558400]
00558400  "Brown"
	Element 1
[da 0x558468]
00558468  "Quick Brown"
	Element 2
[da 0xffffffffcdcdcdcd]
cdcdcdcd  "????????????????????????????????"
cdcdcded  "????????????????????????????????"
cdcdce0d  "????????????????????????????????"
cdcdce2d  "????????????????????????????????"
cdcdce4d  "????????????????????????????????"
cdcdce6d  "????????????????????????????????"
cdcdce8d  "????????????????????????????????"
cdcdcead  "????????????????????????????????"
cdcdcecd  "????????????????????????????????"
cdcdceed  "????????????????????????????????"
cdcdcf0d  "????????????????????????????????"
cdcdcf2d  "????????????????????????????????"

C++: How to clear the input stream?

What do you expect from the following program?

char x = 0;
std::cout << "Enter a character: " << std::endl;
std::cin >> x;
std::cout << "You entered " << x << std::endl;

int y;
std::cout << "Enter a number: " << std::endl;
std::cin >> y;
std::cout << "You entered " << y << std::endl;

If you enter multiple characters for first input (cin >> x), the stream will take the first character and make it not to prompt for the next input as the input buffer contains additional data. How to deal with such a situation?

There’s a high chance to misinterpret cin.clear() which is actually supposed to sets a new value for the error control state. Standard C/C++ input streams are buffered. The keypresses are buffered by operating system, not by the program. If you’re sure that unnecessary data is present in input stream. You can make use of istream::ignore function to extract and discard the remaining data in the input stream. (Alternatively, you can recursively call cin.get() to make sure that all the data in the buffer are consumed). See the snippet below

char x = 0;
std::cout << "Enter a character: " << std::endl;
std::cin >> x;
std::cout << "You entered " << x << std::endl;

// Clear the stream
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// alternative method
// while( !cin.eof() && cin.get() == '\n' );

int y;
std::cout << "Enter a number: " << std::endl;
std::cin >> y;
std::cout << "You entered " << y << std::endl;

2010-06-29 – 4:46 PM IST – Updated Angelo’s comment

Proudly powered by WordPress
Theme: Esquire by Matthew Buchanan.