Hackers

PostHeaderIcon zero pointer to avoid reuse

Sometimes we use pointers, after a pointer is deleted(or freed) it should not be used, that doesn’t prevent bad code from using it though, you know pointers can cause unknown problems, it also one of the toughest problems to debug.

Here’s an example of what were talking about:

	int* data;
	data=new int[10];
	data[0]=0;
	// ...

	delete[] data;

	// ...
	// memory corruption
	data[2]=2;

You should set the pointer to NULL after deleting or free it.

	delete[] data;
	data=NULL;

The result is that on most systems if you try and use the pointer, the system will crash.

	// ...thousand lines of code
	data[2]=2; // system crashes

In this way it does not prevent errors but change them, accessing a memory pointer after it is deleted can result in data corruption or heap corruption. The results of this error may not show up for a long time(especially big memory today) and will probably happen when you are executing a totally unrelated piece of code.
So remember reset pointer after each use.

16,213 views

PostHeaderIcon use assert

The code below compile and execute fine but will also corrupt memory:

	// bad code
	int data[10];
	// ...
	int i=11;
	// memory corruption
	data[i]=5;

For this situation we can use assert to check array accesses.
The following example is recommended way.

	// good code
	#include <cassert>
	int data[10];
	// ...
	int i=11;
	assert((i>=0) && (i<10));
	data[i]=5;

This works but we’ve used the constant 10 in two places(the declaration and the assert). It would be easy for someone to change one and not the other.

One solution to this is to use named constants.

	// good code
	#include <cassert>
	const int DATA_SIZE = 10;
	int data[DATA_SIZE];
	// ...
	int i=11;
	assert((i>=0) && (i<DATA_SIZE));

	data[i]=5;

One better way to do this is using the data variable itself:

	assert((i>=0) && (i<sizeof(data)/sizeof(data[0]));

also you can create a macro or function for code reuse.

attention:assert is invalid with NDEBUG mode.
you can deal this with article verify vs assert

15,710 views

PostHeaderIcon fgets replace gets

Now almost everyone knows the gets can cause the security and reliability problems.

The code below is an example:

// Really bad code
char line[100];
gets(line);

Because gets does not do bounds checking a string longer than 100 characters will overwrite memory. If you are lucky the program will just crash. Obviously,this code is a security problem, A attacker can create a carefully constructed string which overwrites the stack and let’s the bad guy execute any code be wants to.

The gets function is so bad,you can use fgets instead:

// good code
char line[100];
fgets(line,sizeof(line),stdin);

The fgets call will not get more data than the variable can hold, this prevents attackers from executing a stack smashing attack.

13,904 views

PostHeaderIcon flush debugging

Sometimes buffering of output can lead to unexpected results, the code below is an example:

void do_stuff()
{
std::cout<<”Hello do_stuff”<<std::endl;
}
int main(int argc, char const *argv[])
{
/* code */
std::cout<<”Doing unrelated stuff”<<std::endl;
do_stuff();
std::cout<<”Doing divide…”;
int i=0;
i=1/0;
std::cout<<”complete”<<std::endl;
return 0;
}

When runs this program prints(on some systems):

Doing unrelated stuff
Hello do_stuff
Floating point exception

This problem is that output is being buffered, so the string “Doing divide …” goes into the buffer, then the crashes with a -Wdiv-by-zero exception,this is where the confusion comes from.

We can deal this situation with std::flush.

one way of doing this is to explicitly flush every statement when debugging:

you have to do the flush for every output statement.
std::cout<<”Doing divide…”<<std::flush;

In this way, you have to remember to do the flush for every statement.

The other way is to set unitbuf flag which tells C++ to flush after every output operation,just do once at the top of your program:

just do once
std::cout<<std::unitbuf;

Being aware of what’s going inside the program is very useful to a programmer,knowing how to get around the internal limitations of the system is the mark of a good programmer.

13,798 views

PostHeaderIcon With Tempalte to Create Array

I’m sorry,long time have no updates, Jan is Chinese Spring Festival,I just go back home and stay with my family.

This month back company and a lot of things to do. several web applications are under developed,but not in C++,

just in Java and PHP.Actually, c++ is my favorite snack.

In your daily C++ programs, array is a common container.maybe you tell me you like vector instead of array,

Ok, good action, enjoy vector in C++.But sometime you have to use array, I do not want a detailed statement

about it.

Let’s begin, it’s so easy. you maybe write better template array than it .

#include <cassert>
template<typename array_type,
	unsigned int size> class array {
	private:
		static const unsigned int ARRAY_SIZE = size;
		array_type data[ARRAY_SIZE];
	public:
		array(void) {};
		array(const array& other_array) {
			memcopy(data, other_array.data, sizeof(data));
		};
		~array() {};
		array& operator = (const array& other_array) {
			memcopy(data, other_array.data, sizeof(data));
			return (*this);
		};
	public:
		array_type& operator[](int index) {
			assert(index >= 0);
			assert(index < ARRAY_SIZE);
			return (&data[index]);
		}
};

Hide the code inside a template, You don’t have to add asserts every time you access an array.

the work is done for you automatically, it includes assert statements which prevent you from

overflowing the array.

But it doesn’t provide a way of converting an array into a pointer.

If you need it,do it yourself.

It is up to you whether or not you consider this a simple way or a bug.

16,955 views

Copyright © 2010 - C++ Technology. All Rights Reserved.

Powered by Jerry | Free Space Provided by connove.com