Assert and Subscript Checking

Xem chủ đề cũ hơn Xem chủ đề mới hơn Go down

Assert and Subscript Checking

Bài gửi by anbinhtrong on Tue Dec 15, 2009 10:04 am

Assert and Subscript Checking

Many of the techniques used in writing robust C code also apply in C++. For example, if you have a function that is supposed to be passed a person's name, as a C-style string, it would be wise to say:
#include

void f(char* name)
{
assert(name && *name);

...
}
to perform basic checks on the passed-in pointer. assert() is a function (actually a macro) that checks whether its argument is true (non-zero), and aborts the program if not.
But C++ offers additional opportunities to the designer interested in producing quality code. For example, consider a common problem in C, where vector bounds are not checked during a dereference operation, and a bad location is accessed or written to.
In C++, you can partially solve this problem by defining a Vector class, with a vector dereferencing class member defined for the Vector, and the vector size stored:

#include
#include

class Vector {

int len; // number of elements
int* ptr; // pointer to elements
public:

Vector(int); // constructor
~Vector(); // destructor
int& operator[](int); // dereferencing
};

//constructor
Vector::Vector(int n)
{

assert(n >= 1);

len = n; // store length
ptr = new int[n]; // get storage to store elements
assert(ptr);
}

//destructor
Vector::~Vector()
{

delete ptr;
}

//dereferencing
int& Vector::operator[](int i) {

assert(i >= 1 && i <= len);

return ptr[i - 1]; // return reference to vector slot
}

//driver program
main() {

int i;
const int N = 10;
Vector v(N);

for (i = 1; i <= N; i++) // correct usage
v[i] = i * i;

for (i = 1; i <= N; i++) // correct usage
printf("%d %d\n", i, v[i]);

v[0] = 0; // will trigger assert failure

return 0;
}

In this example, we create a vector of 10 elements, and the vector is indexed 1..10. If the vector is dereferenced illegally, as in:
v[0] = 0;
an assertion failure will be triggered.
One objection to this technique is that it can be slow. If every vector reference requires a function call (to Vector::operator[]), then there may be a large performance hit. However, performance concerns can be dealt with by making the dereferencing function inline.
Two other comments about the above example. We are assuming in these newsletters that if operator new() fails, it returns a NULL pointer:
ptr = new int[n];
assert(ptr); // check for non-NULL pointer
The current draft ANSI standard says that when such a failure occurs, an exception is thrown or else a new handler is invoked. Because many C++ implementations still use the old approach of returning NULL, we will stick with it for now.
The other comment concerns the use of references. In the code:
v[i] = i * i;
the actual code is equivalent to:
v.operator[](i) = i * i;
and could actually be written this way (see a C++ reference book on operator overloading for details).
Vector::operator[] returns a reference, which can be used on the left-hand side of an assignment expression. In C the equivalent code would be more awkward:
Code:
#include <stdio.h>
int x[10]; // use f() to index into x[10]
int* f(int i) {

        return &x[i - 1];
}

main() {

        *f(5) = 37;

        printf("%d %d\n", *f(5), x[4]);

        return 0;
}
avatar
anbinhtrong
Admin
Admin

Tổng số bài gửi : 216
Join date : 05/11/2009
Age : 28
Đến từ : BT

Xem lý lịch thành viên http://ngoctho.forum-viet.net

Về Đầu Trang Go down

Xem chủ đề cũ hơn Xem chủ đề mới hơn Về Đầu Trang


 
Permissions in this forum:
Bạn không có quyền trả lời bài viết