关于函数返回值为指针类型的分析
|
|
(1)可以使用全局数组。使用全局变量时,在程序结束时才释放。
(2)在函数GetString()中使用new在堆上动态分配内存来建立数组。C语言中可以使用malloc()函数。不过不要忘记了,在使用完后要进行内存的释放,不然会造成内存的泄漏。分别用delete,free(),释放。使用delete时,会调用类的析构函数,而free则不会。
|
|
|
|
|
|
(5)使用字符串常量,因为字符串常量存储再静态存储区域,所以一直都存在,p是临时变量,但过程结束并不会释放这个字符串常量.而p[]就不一样了,它是一个数组,数组里面存放了字符串,这个字符串没有放在字符串常量存储再静态存储区域,p是临时变量,跳出函数之后一般保留一步就释放了,数组的空间回收了,字符串没有了。
|
|
一般在函数中定义一个对象有两种方法:
1、在栈上建立局部变量。注意,在栈上时!栈用于函数是为了返回时找得到调用点(在调用时压入栈的) ,那么,返回时要POP才能得到。函数体中建立的任何东西都消失了(返回值除外),你返回的指针指向的内 容现在不知被用作什么用途了,如果你还要修改的话,那么后果不能确定。
2、在堆中分配。返回时不会摧毁,因为堆是全局存在的。但函数的调用者要记得delete回来的指针。
看以下程序:
==========================================================================
char* GetFileName()
{
char filename[] = “file_0001.dat”;
strcpy(filename,"file_xxxx");
return filename;
}
void main()
{
char* s;
s = GetFileName();
printf(“%s
”, s);
}
=============================================================================
编译程序出错,提示为:
warning C4172: returning address of local variable or temporary
意思就是说,不能试图把局部变量的指针作为函数的返回值。
为什么?
函数作为独立的模块,在其内部声明和使用的变量都是局部变量,他们都是存在栈上的,当函数调用完成时,会清理掉这些局部变量,这样在调用完函数后再企图通过返回的局部变量指针得到局部变量是非法的。
但是,有个例外情况,就是在C语言中使用malloc函数分配的指针变量是在堆上动态分配的,它不受函数生命周期的影响,因此在函数调用并结束后,使用malloc分配的指针仍然有效。对于C++中的new操作符,同样因为是在堆上面分配内存,不会丢掉,可以在函数调用结束后继续访问。
注意,因为使用了malloc函数或new操作符,在程序结束前,我们就要显示地使用free函数或者delete指令销毁之前分配的堆变量指针。
例:
void* getData(ATTR attribute)
{
int i;
uchar* singleUbyte = NULL;
ushort* singleUint16 = NULL;
ulong* singleUint32 = NULL;
short* singleSint16 = NULL;
long* singleSint32 = NULL;
real* singleReal32 = NULL;
VALUE * vData = NULL;
PositionUByte* posUByte = NULL;
PositionUShort* posUShort = NULL;
PositionULong* posULong = NULL;
PositionShort* posShort = NULL;
PositionLong* posLong = NULL;
PositionFloat* posFloat = NULL;
BoxUByte* boxUByte = NULL;
BoxUShort* boxUShort = NULL;
BoxULong* boxULong = NULL;
BoxShort* boxShort = NULL;
BoxLong* boxLong = NULL;
BoxReal* boxReal = NULL;
if(attribute.data.param.type == Single)
switch (attribute.data.param.size)
{
case Ubyte:
singleUbyte = (uchar*)malloc(sizeof(uchar));
*singleUbyte = attribute.data.param.t.s.ubyte;
return singleUbyte;
case Uint16:
singleUint16 = (ushort*)malloc(sizeof(ushort));
*singleUint16 = attribute.data.param.t.s.uint16;
return singleUint16;
case Uint32:
singleUint32 = (ulong*)malloc(sizeof(ulong));
*singleUint32 = attribute.data.param.t.s.uint32;
return singleUint32;
case Sint16:
singleSint16 = (short*)malloc(sizeof(short));
*singleSint16 = attribute.data.param.t.s.sint16;
return singleSint16;
case Sint32:
singleSint32 = (long*)malloc(sizeof(long));
*singleSint32 = attribute.data.param.t.s.sint32;
return singleSint32;
case Real32:
singleReal32 = (real*)malloc(sizeof(real));
*singleReal32 = attribute.data.param.t.s.real32;
return singleReal32;
default:
break;
}
if(attribute.data.param.type == Xy)
switch (attribute.data.param.size)
{
case Ubyte:
posUByte = (PositionUByte*)malloc(sizeof(PositionUByte));
posUByte->x = attribute.data.param.t.xy.v1.ubyte;
posUByte->y = attribute.data.param.t.xy.v2.ubyte;
return posUByte;
case Uint16:
posUShort = (PositionUShort*)malloc(sizeof(PositionUShort));
posUShort->x = attribute.data.param.t.xy.v1.uint16;
posUShort->y = attribute.data.param.t.xy.v2.uint16;
return posUShort;
case Uint32:
posULong = (PositionULong*)malloc(sizeof(PositionULong));
posULong->x = attribute.data.param.t.xy.v1.uint32;
posULong->y = attribute.data.param.t.xy.v2.uint32;
return posULong;
case Sint16:
posShort = (PositionShort*)malloc(sizeof(PositionShort));
posShort->x = attribute.data.param.t.xy.v1.sint16;
posShort->y = attribute.data.param.t.xy.v2.sint16;
return posShort;
case Sint32:
posLong = (PositionLong*)malloc(sizeof(PositionLong));
posLong->x = attribute.data.param.t.xy.v1.sint32;
posLong->y = attribute.data.param.t.xy.v2.sint32;
return posLong;
case Real32:
posFloat = (PositionFloat*)malloc(sizeof(PositionFloat));
posFloat->x = attribute.data.param.t.xy.v1.real32;
posFloat->y = attribute.data.param.t.xy.v2.real32;
return posFloat;
default:
break;
}
if(attribute.data.param.type == Box)
switch (attribute.data.param.size)
{
case Ubyte:
boxUByte = (BoxUByte*)malloc(sizeof(BoxUByte));
boxUByte->left = attribute.data.param.t.b.v1.ubyte;
boxUByte->top = attribute.data.param.t.b.v2.ubyte;
boxUByte->right = attribute.data.param.t.b.v3.ubyte;
boxUByte->bottom = attribute.data.param.t.b.v4.ubyte;
return boxUByte;
case Uint16:
boxUShort = (BoxUShort*)malloc(sizeof(BoxUShort));
boxUShort->left = attribute.data.param.t.b.v1.uint16;
boxUShort->top = attribute.data.param.t.b.v2.uint16;
boxUShort->right = attribute.data.param.t.b.v3.uint16;
boxUShort->bottom = attribute.data.param.t.b.v4.uint16;
return boxUShort;
case Uint32:
boxULong = (BoxULong*)malloc(sizeof(BoxULong));
boxULong->left = attribute.data.param.t.b.v1.uint32;
boxULong->top = attribute.data.param.t.b.v2.uint32;
boxULong->right = attribute.data.param.t.b.v3.uint32;
boxULong->bottom = attribute.data.param.t.b.v4.uint32;
return boxULong;
case Sint16:
boxShort = (BoxShort*)malloc(sizeof(BoxShort));
boxShort->left = attribute.data.param.t.b.v1.sint16;
boxShort->top = attribute.data.param.t.b.v2.sint16;
boxShort->right = attribute.data.param.t.b.v3.sint16;
boxShort->bottom = attribute.data.param.t.b.v4.sint16;
return boxShort;
case Sint32:
boxLong = (BoxLong*)malloc(sizeof(BoxLong));
boxLong->left = attribute.data.param.t.b.v1.sint32;
boxLong->top = attribute.data.param.t.b.v2.sint32;
boxLong->right = attribute.data.param.t.b.v3.sint32;
boxLong->bottom = attribute.data.param.t.b.v4.sint32;
return boxLong;
case Real32:
boxReal = (BoxReal*)malloc(sizeof(BoxReal));
boxReal->left = attribute.data.param.t.b.v1.real32;
boxReal->top = attribute.data.param.t.b.v2.real32;
boxReal->right = attribute.data.param.t.b.v3.real32;
boxReal->bottom = attribute.data.param.t.b.v4.real32;
return boxReal;
default:
break;
}
if(attribute.data.param.type == Array)
vData = attribute.data.param.t.a.valp;
switch (attribute.data.param.size)
{
case Ubyte:
singleUbyte = (uchar*)malloc(attribute.data.param.t.a.len*sizeof(uchar));
for(i = 0;i < attribute.data.param.t.a.len;i++)
{
singleUbyte[i] = (*vData).ubyte;
vData++;
}
return singleUbyte;
case Uint16:
singleUint16 = (ushort*)malloc(attribute.data.param.t.a.len*sizeof(ushort));
for(i = 0;i < attribute.data.param.t.a.len;i++)
{
singleUint16[i] = (*vData).uint16;
vData++;
}
return singleUint16;
case Uint32:
singleUint32 = (ulong*)malloc(attribute.data.param.t.a.len*sizeof(ulong));
for(i = 0;i < attribute.data.param.t.a.len;i++)
{
singleUint32[i] = (*vData).uint32;
vData++;
}
return singleUint32;
case Sint16:
singleSint16 = (short*)malloc(attribute.data.param.t.a.len*sizeof(short));
for(i = 0;i < attribute.data.param.t.a.len;i++)
{
singleSint16[i] = (*vData).sint16;
vData++;
}
return singleSint16;
case Sint32:
singleSint32 = (long*)malloc(attribute.data.param.t.a.len*sizeof(long));
for(i = 0;i < attribute.data.param.t.a.len;i++)
{
singleSint32[i] = (*vData).sint32;
vData++;
}
return singleSint32;
case Real32:
singleReal32 = (float*)malloc(attribute.data.param.t.a.len*sizeof(float));
for(i = 0;i < attribute.data.param.t.a.len;i++)
{
singleReal32[i] = (*vData).real32;
vData++;
}
return singleReal32;
default:
break;
}
return NULL;
}
