注册 登录
编程论坛 C++教室

指针的释放方式

vfdff 发布于 2008-11-23 01:00, 1993 次点击
#include   <stdio.h>  
#include   <stdlib.h>
#include   <malloc.h>
#include   <assert.h>
double *Alloc_Double_Array(long length)
{
    double *array = NULL;
   
    if( NULL == (array = new double [length]) )
    {
        fprintf(stdout, "Merory Exhausted\n");
        return NULL;
    }
   
    //memset(array, 0, length*sizeof(double));
    return array;
}

template <typename T>
void Free_Array (T **array)
{   
    assert( array != NULL);
    //printf("array=0x%p,*array=0x%p\n",array,*array);
    delete  *array;
} // Free_Array(&p1);

template <typename T>
void FreeArray (T *array)
{   
    assert( array != NULL);
    delete  *array;
} // Free_Array(&p2);

int main()  
{  
    double *p1 = Alloc_Double_Array(0x100);
    double *p2 = Alloc_Double_Array(0x100);
    printf("p1=0x%p,p2=0x%p\n",p1,p2);
    p1[0] = 1.3;
    p2[0] = 2.3;

    Free_Array(&p1);
    printf("first\n");
    p1 = Alloc_Double_Array(0x100);
    p1[0] = 1.3;
    p2[0] = 2.3;
    printf("p1=0x%p,p2=0x%p\n",p1,p2);

    FreeArray(&p2);
    printf("second\n");
    p2 = Alloc_Double_Array(0x100);
    p1[0] = 1.3;
    p2[1] = 2.3;
    printf("p1=0x%p,p2=0x%p\n",p1,p2);
    return 0;
}
为什么采用上述两种方法释放指针均正确》》
7 回复
#2
debroa7232008-11-23 20:19
这两个没有区别,都是把参数array的指向内容做为指针来删除,

Free_Array(&p1);//模板T => double       这样,参数类型就是double **
FreeArray(&p2);// 模板T => double *     这样,参数类型还是double ** 和上面的没区别
FreeArray(p2);// 模板T => double      这样,参数类型是double * array 这种情况在运行到delete  *array;时出错.
我认为FreeArray的功能是删除指针,而Free_Array的功能是删除指针的指针,否则没有必要写两个,因为实现代码全一样的,功能一样.
应该这样写:
template <typename T>
void Free_Array (T array)
{   
    assert( array != NULL && *array != NULL );
    delete  *array;
}

template <typename T>
void FreeArray (T array)
{   
    assert( array != NULL);
    delete  array;
}
如下调用
Free_Array(&p1);
FreeArray(p2);
//使用断言如果指针为空就很麻烦,但这样就要求使用该函数的人非常小心传于的参数,严格起来,这种情况只适合指针必须有合法内容的逻辑代码中,如果是在需要可以传入空指针的情况,并在空指针的情况下做其它的处理时,使用断言并不好,要使用返回错误码的方式,使得调用者在外部可以根据不同情况做不同处理.如下:

template <typename T>
int Free_Array (T array)
{   
    if( array == NULL )
    {
         return 1 ;
    }else if( *array != NULL )
    {
         return 2 ;
    }
    delete  *array;
    *array = NULL ;
    return 0 ;
}
不同的返回值做不同的逻辑处理
#3
vfdff2008-11-23 22:47
回复 第2楼 debroa723 的帖子
为什么您不主张 使用
template <typename T>
void FreeArray (T *array)
或者
template <typename T>
void FreeArray (T **array) 这种方式,明确以指针的形式出现呢??
#4
debroa7232008-11-23 23:54
并不是不主张,习惯问题.
因为是两种功能的函数,只要从函数名上去决定如何传递参数.
不过你说的对,模板这东西不是写了后自己用的,可能别人也会用,象这样从函数名上没有明确的功能表示的函数,用参数来表达功能会给其它使用者更多的信息了解.
我习惯用函数名来表达函数功能,再加上注释,如:
template <typename T>
void FreePP(T array)//删除指针的指针
template <typename T>
void FreeP(T array)//删除指针
#5
aipb20072008-11-24 00:09
2楼很精彩,楼主也很善于思考。获益良多,呵呵
#6
中学者2008-11-24 22:57
不知LZ发觉没有,你这样泛型的意义不大.....直接用伪多态扩展性更好:
void FreeArray (void *array)
{   
     //另做处理
}
仅此建议.  有错请纠~
#7
vfdff2008-11-25 00:39
回复 第6楼 中学者 的帖子
我觉得使用
void FreeArray (void *array)
{   
     //另做处理
} 这种方法,在使用的时候,需要把别的类型强制转换到 void *类型,使用时有点累赘,所以才想用模板
#8
中学者2008-11-25 12:53
确实,用void*要灵活运用偏移量...但是你泛型的话就会出现2L说的情况,而且更重要的一点是void*可以帮你在编译期找出泛型找不到的那个严重错误(很可能导致崩溃):
   FreeArray(p2);
1