请教一道华为的面试题!

winsunII 2003-09-28 06:15:45
找出下面代码的潜在问题:

class C
{
int * iCount;

public:
void clear()
{
if(iCount) delete iCount;
}
C(){iCount = new int;}
~C(){clear();}
};
...全文
29 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
见招拆招 2003-10-23
  • 打赏
  • 举报
回复
mark
tryber 2003-09-28
  • 打赏
  • 举报
回复
凑个数:有个叫林锐的高人,在《高质量的C/C++代码》中说这样的代码风格不提倡,
if(anyvar)
...
而要用这种风格,可读性和健壮性较好,要不然在java中也不会不放过它了:-)
if(anyvar!=0)
//对于变量,对于布尔变量虽不会引起误会,但还是要小心,
//因为vc实现上直接typedef int BOOL 了事
{
...
}

if(panyvar!=NULL) //对于指针
{
...
}
xueweizhong 2003-09-28
  • 打赏
  • 举报
回复
类有一个很重要的性质就是其不变量(class invariant)

一般来讲:
1: 在类的构造函数中创建invariant
2: 在函数中维护这个不变量。

在这个类:
class C
{
int * iCount;

public:
void clear()
{
if(iCount) delete iCount; // ---#2
}
C(){iCount = new int;} // ---#1
~C(){clear();}
};

中一般来讲不变量为
iCount == 0 或
iCount 指向堆对象且拥有这个对象(即delete iCount操作有效)

#1 构造函数建立这个不变量。
这个函数没有问题:
如果 new int 抛出异常,
1: 表示没有分配堆对象,不会导致内存泄漏
2: 构造函数抛出异常,将传递给调用者,语言将保证这种机制的正确性。

#2 clear()函数就有些问题:
因为clear()函数调用后对象还是存在,但是
iCount指向已经被释放的堆对象,不再满足class invariant

当然还有其他问题种种,上面大家都已经提到了。
chinajiji 2003-09-28
  • 打赏
  • 举报
回复
肯定会有问题的,iCount将被delete两次,在有的编译器中会出现rutime error,有的则可能不会出现,但并不说明不会有潜在的问题.
ttlb 2003-09-28
  • 打赏
  • 举报
回复
不是的,运行的时候没问题,但debug的时候就不行了。
我记得以前这种情况运行的时候应该出问题才对,但这次居然?
ttlb 2003-09-28
  • 打赏
  • 举报
回复
tolixiaohui(lxh) 说得对呀,我把程序试了一遍,没出任何问题呀。不过我的析构函数也执行了。
tolixiaohui 2003-09-28
  • 打赏
  • 举报
回复
为什么析构函数不执行了!!!
tolixiaohui 2003-09-28
  • 打赏
  • 举报
回复
#include <iostream.h>
#include <stdlib.h>

class C
{
int * iCount;

public:
void clear()
{
if(iCount) delete iCount;
cout << "clear" << endl;
}
C()
{
iCount = new int;
cout << "constuctor" << endl;
}
~C()
{
clear();
cout << "destuctor" << endl;
}
};

void main()
{
C a;
a.clear();
system("pause");
}



constuctor
clear
请按任意键继续 . . .

结果没什么问题!(除了析构函数)
sdtea 2003-09-28
  • 打赏
  • 举报
回复
凡是有内部指针的,自己申请内存,一定要写赋值构造和拷贝构造,看看effective c++
chinajiji 2003-09-28
  • 打赏
  • 举报
回复
#include <iostream>
#include <stdlib.h>
using namespace std;

class C
{
int * iCount;

public:
/* 这个函数是脱裤子打屁多此一举.
void clear()
{
if(iCount) delete iCount;
}
*/
C(){iCount = new int(0);} // intialize the memory pointed by iCount
// with 0;
// copy constructor and operator= is very importan in this case!
// here, using deep copy and assignment simply.
C(const C &rhv)
{ iCount = new int;
if(iCount == NULL)
{
cout << "memory overflow!" << endl;
exit(-1);
}
*iCount = *rhv.iCount;
}
C& operator=(const C &rhv)
{
*iCount = *rhv.iCount;
return *this;
}
~C()
{
delete iCount; // Don't need to check if iCount is a null pointer.
iCount = NULL; // turn icount into a null pointer is good,
// omit this step is ok too;
}
// for print.
friend ostream& operator<<(ostream& os, const C &c)
{
return os << *c.iCount;
}
// for test;
C(int i)
{
iCount = new int(i);
if(iCount == NULL)
{
cout << "memory overflow!" << endl;
exit(-1);
}
}
};

int main() {
C a;
cout << "a = " << a << endl;
C *pb = new C(999);
cout << "*pb = " << *pb << endl;
C *pc = new C(*pb);
cout << "*pc = " << *pc << endl;
delete pc;
C *pd =new C(888);
*pb = *pd;
cout << "*pb = " << *pb << endl;
delete pb;
cout << "*pd = " << *pd << endl;
delete pd;
system("pause");
return 0;
}
goldencz 2003-09-28
  • 打赏
  • 举报
回复
to chenyc(兽医)

如果new失败的话,返回的值是0,所以你的说法是不成立的
winsunII 2003-09-28
  • 打赏
  • 举报
回复
同意 Jinhao(辣子鸡丁) 和 njtu(天地不容) 的说法

Meyer 2003-09-28
  • 打赏
  • 举报
回复
主要问题是
delete iCount;
并没有修改
iCount = 0;
造成空悬指针。
Jupin 2003-09-28
  • 打赏
  • 举报
回复
study
Jinhao 2003-09-28
  • 打赏
  • 举报
回复
楼上的兄弟想得这么有深度,学习ING...
njtu 2003-09-28
  • 打赏
  • 举报
回复
class C
{
int * iCount;
private:
//该函数不要定义成public
void clear()
{
if(iCount)
{
delete iCount;
iCount = NULL;
}
}

public:
//这里可能有失败的问题,但应该不是重点
C(){ iCount = new int;}
~C(){clear();}
};

还应该特殊处理该类相关的;
拷贝构造函数
附值操作符
因为必须对该函数进行深拷贝
Jinhao 2003-09-28
  • 打赏
  • 举报
回复
华为是什么,哪儿的??????????
我是重庆的,天不怕地不怕,就怕重庆姑娘

我开先也想到new失败,就是忘了写,如果不catch的话,程序就自己退出
hijack 2003-09-28
  • 打赏
  • 举报
回复
operator =
chenyc 2003-09-28
  • 打赏
  • 举报
回复
Jinhao(辣子鸡丁)说得也是一个问题。赞成!

你们都是华为外包的吗?留个QQ:44435878
chenyc 2003-09-28
  • 打赏
  • 举报
回复
.....
if(iCount) delete iCount;//这句话有问题
....

如果NEW失败的话,这句话就会出错。
改为:

C(){iCount = new int;assert(iCount!=NULL);}
加载更多回复(4)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧