指针的验证
在指针使用之前,不检测是非常普遍的,这个可以说是我们引起软件崩溃最有可能的原因。如果你用一个指针,这个指针刚好是NULL,那么你的程序在运行时,将报出异常。
CVehicle* pVehicle = GetCurrentVehicle();
// Validate pointer
if(pVehicle==NULL)
{
// Invalid pointer, do not use it!
return FALSE;
}
// Validate pointer
if(pVehicle==NULL)
{
// Invalid pointer, do not use it!
return FALSE;
}
如果你的函数创建了一个对象,并要将它作为函数的返回参数。那么记得在使用之前把他复制为NULL。如不然,这个函数的调用者将使用这个无效的指针,进而一起程序错误。如下错误代码:
int CreateVehicle(CVehicle** ppVehicle)
{
if(CanCreateVehicle())
{
*ppVehicle = new CVehicle();
return 1;
}
// If CanCreateVehicle() returns FALSE,
// the pointer to *ppVehcile would never be set!
return 0;
}
正确的代码如下;
int CreateVehicle(CVehicle** ppVehicle)
{
// First initialize the output parameter with NULL
*ppVehicle = NULL;
if(CanCreateVehicle())
{
*ppVehicle = new CVehicle();
return 1;
}
return 0;
}
{
if(CanCreateVehicle())
{
*ppVehicle = new CVehicle();
return 1;
}
// If CanCreateVehicle() returns FALSE,
// the pointer to *ppVehcile would never be set!
return 0;
}
正确的代码如下;
int CreateVehicle(CVehicle** ppVehicle)
{
// First initialize the output parameter with NULL
*ppVehicle = NULL;
if(CanCreateVehicle())
{
*ppVehicle = new CVehicle();
return 1;
}
return 0;
}
清理已删除对象的指针
在内存释放之后,无比将指针复制为NULL。这样可以确保程序的没有那个地方会再使用无效指针。其实就是,访问一个已经被删除的对象地址,将引起程序异常。如下代码展示如何清除一个指针指向的对象:
// Create object
CVehicle* pVehicle = new CVehicle();
delete pVehicle; // Free pointer
pVehicle = NULL; // Set pointer with NULL
CVehicle* pVehicle = new CVehicle();
delete pVehicle; // Free pointer
pVehicle = NULL; // Set pointer with NULL
在释放一个句柄之前,务必将这个句柄复制伪NULL (0或则其他默认值)。这样能够保证程序其他地方不会重复使用无效句柄。看看如下代码,如何清除一个Windows API的文件句柄:
HANDLE hFile = INVALID_HANDLE_VALUE;
// Open file
hFile = CreateFile(_T("example.dat"), FILE_READ|FILE_WRITE, FILE_OPEN_EXISTING);
if(hFile==INVALID_HANDLE_VALUE)
{
return FALSE; // Error opening file
}
// Do something with file
// Finally, close the handle
if(hFile!=INVALID_HANDLE_VALUE)
{
CloseHandle(hFile); // Close handle to file
hFile = INVALID_HANDLE_VALUE; // Clean up handle
}
// Open file
hFile = CreateFile(_T("example.dat"), FILE_READ|FILE_WRITE, FILE_OPEN_EXISTING);
if(hFile==INVALID_HANDLE_VALUE)
{
return FALSE; // Error opening file
}
// Do something with file
// Finally, close the handle
if(hFile!=INVALID_HANDLE_VALUE)
{
CloseHandle(hFile); // Close handle to file
hFile = INVALID_HANDLE_VALUE; // Clean up handle
}
下面代码展示如何清除File *句柄:
// First init file handle pointer with NULL
FILE* f = NULL;
// Open handle to file
errno_t err = _tfopen_s(_T("example.dat"), _T("rb"));
if(err!=0 || f==NULL)
return FALSE; // Error opening file
// Do something with file
// When finished, close the handle
if(f!=NULL) // Check that handle is valid
{
fclose(f);
f = NULL; // Clean up pointer to handle
}
FILE* f = NULL;
// Open handle to file
errno_t err = _tfopen_s(_T("example.dat"), _T("rb"));
if(err!=0 || f==NULL)
return FALSE; // Error opening file
// Do something with file
// When finished, close the handle
if(f!=NULL) // Check that handle is valid
{
fclose(f);
f = NULL; // Clean up pointer to handle
}