某该错面试题

gattuso8 2008-11-24 10:00:41
#include <string.h>
#include <stdio.h>
class Base
{ private:
char * name;
public:
Base(char * className)
{
name = new char[strlen(className)];
strcpy(name, className);
}
~Base()
{delete name;}
char * copyName()
{
char newname [256];
strcpy(newname, name);
return newname;
}
char * getName()
{return name;}
static void print(Base base)
{printf("name: %s\n" , base.name);}
};
class Subclass : public Base
{
public:
Subclass(char * className) : Base(className)
{ }
};
int main()
{
Base * pBase = new Subclass("test");
Base::print(*pBase);
printf("name: %s\n", pBase->getName());
printf("new name: %s\n", pBase->copyName());
return 0;
}

就是在调用Base::print(*pBase);时崩溃的
把传参类型改成引用或指针就没问题
于是怀疑是拷贝构造函数的问题,
可是我加了个拷贝构造函数 问题依旧
不知道具体原因是什么。
...全文
163 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
就呆在云上 2008-11-24
  • 打赏
  • 举报
回复
我的意思是 打印此函数的返回值 
居然能正确打印
也就是说newname在返回后 没有被马上析构
猜想可能跟编译器的实现策略有关系


析构了
呵呵
只是内容没有被替换
gattuso8 2008-11-24
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 cyj626 的回复:]
引用 12 楼 gattuso8 的回复:
谢谢各位 貌似有道理
1 崩溃确实是跟浅拷贝有关
2 char * copyName()
{
char newname [256];
strcpy(newname, name);
//不可以返回临时变量的指针或引用
return newname;
}
这段我也很不理解
我也认为返回栈上的变量是不合适的
但程序在VC6运行似乎没问题。

你可以试试把newname的打印出来看看就知道为什么了,举个例子吧。
[/Quote]

我的意思是 打印此函数的返回值
居然能正确打印
也就是说newname在返回后 没有被马上析构
猜想可能跟编译器的实现策略有关系
cyj626 2008-11-24
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 gattuso8 的回复:]
谢谢各位 貌似有道理
1 崩溃确实是跟浅拷贝有关
2 char * copyName()
{
char newname [256];
strcpy(newname, name);
//不可以返回临时变量的指针或引用
return newname;
}
这段我也很不理解
我也认为返回栈上的变量是不合适的
但程序在VC6运行似乎没问题。
[/Quote]
你可以试试把newname的打印出来看看就知道为什么了,举个例子吧。
love514425 2008-11-24
  • 打赏
  • 举报
回复
不可以返回临时变量的指针或引用

>是因为如果你在返回前把这块内存释放了,那么函数返回的指针就指向了一块非法内存,成了“野指针”,试图访问“野指针”指向的内存会导致运行时错误,这种错误是很难定位的。
gattuso8 2008-11-24
  • 打赏
  • 举报
回复
谢谢各位 貌似有道理
1 崩溃确实是跟浅拷贝有关
2 char * copyName()
{
char newname [256];
strcpy(newname, name);
//不可以返回临时变量的指针或引用
return newname;
}
这段我也很不理解
我也认为返回栈上的变量是不合适的
但程序在VC6运行似乎没问题。
love514425 2008-11-24
  • 打赏
  • 举报
回复

// test7.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string.h>
#include <stdio.h>
#include <iostream>
using namespace std;

class Base
{
private:
char * name;
public:
Base(char * className)
{
name = new char[strlen(className)];
strcpy(name, className);
}
~Base()
{
delete[] name;
}
char * copyName()
{
char newname [256];
strcpy(newname, name);
return newname;
}
char * getName()
{
return name;
}
static void print(const Base &base) //此处使用引用
{
printf("static name: %s\n" ,base.name);
}
};
class Subclass : public Base
{
public:
Subclass(char * className) : Base(className)
{
}
};
int main()
{
Base * pBase = new Subclass("test");
Base::print(*pBase);
printf("name: %s\n", pBase->getName());
printf("new name: %s\n", pBase->copyName());
system("pause");
return 0;
}

jia_xiaoxin 2008-11-24
  • 打赏
  • 举报
回复
#include <string.h> 
#include <stdio.h>
class Base
{
private:
char * name;
public:
Base(char * className)
{
int n = strlen(className);
//给字符串指针分配空间时,需要多分配一个空结尾
name = new char[strlen(className)+1];
strcpy(name, className);
name[strlen(className)] = '\0';
}
~Base()
{delete name;}
char * copyName()
{
char newname [256];
strcpy(newname, name);
//不可以返回临时变量的指针或引用
return newname;
}

char * getName()
{return name;}
//需要按引用传递,因为你没有实现深拷贝
static void print(Base &base)
{printf("name: %s\n" , base.name);}
};
class Subclass : public Base
{
public:
Subclass(char * className) : Base(className)
{ }
};
int main()
{
Base * pBase = new Subclass("test");
Base::print(*pBase);
printf("name: %s\n", pBase->getName());
printf("new name: %s\n", pBase->copyName());
return 0;
}
heshang10 2008-11-24
  • 打赏
  • 举报
回复
char * copyName()
{
char newname [256];
strcpy(newname, name);
return newname;
}
此处有错吧 ,定义的数组是在栈上的空间,当函数结束时空间也随即释放,不能进行传递,只能动态的申请空间
就呆在云上 2008-11-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 gattuso8 的回复:]
引用 5 楼 elephont9527 的回复:
static void print(Base base)
{printf("name: %s\n" , base.name);}
};
传值会调用拷贝构造,产生一个临时对象,这个对象的name也指向同一块内存,当print调用结束后对象析构,name指向的内存就delete了,pBase->name指向的就是乱码


临时对象怎么可能会和我new的对象指向同一内存呢?
事实上 我把这两句改写成
static void print(Base base)
{printf("abc");}
程序一样会…
[/Quote]

baidu:浅copy
就晓得怎么回事了
gattuso8 2008-11-24
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 elephont9527 的回复:]
static void print(Base base)
{printf("name: %s\n" , base.name);}
};
传值会调用拷贝构造,产生一个临时对象,这个对象的name也指向同一块内存,当print调用结束后对象析构,name指向的内存就delete了,pBase->name指向的就是乱码
[/Quote]

临时对象怎么可能会和我new的对象指向同一内存呢?
事实上 我把这两句改写成
static void print(Base base)
{printf("abc");}
程序一样会崩溃的

我觉得 崩溃跟static有关
就呆在云上 2008-11-24
  • 打赏
  • 举报
回复
不能用非引用做参数是因为
你没有自带的复制构造函数,呵呵,系统帮你生成了一个浅copy的函数
那么生成的临时对象就会析构原来的内存,两次析构一处,当然报错
elephont9527 2008-11-24
  • 打赏
  • 举报
回复
static void print(Base base)
{printf("name: %s\n" , base.name);}
};
传值会调用拷贝构造,产生一个临时对象,这个对象的name也指向同一块内存,当print调用结束后对象析构,name指向的内存就delete了,pBase->name指向的就是乱码
gattuso8 2008-11-24
  • 打赏
  • 举报
回复
楼上两位
我知道改成引用或者就指针就没问题了啊
我不明白的是传值为什么不行呢?
yang1216 2008-11-24
  • 打赏
  • 举报
回复
楼上很对,另外name = new char[strlen(className)]; 是不是要写成name = new char[strlen(className)+1];
就呆在云上 2008-11-24
  • 打赏
  • 举报
回复

#include <string.h>
#include <stdio.h>
class Base
{ private:
char * name;
public:
Base(char * className)
{
name = new char[strlen(className)];
strcpy(name, className);
}
~Base()
{delete []name;} /////////////////////使用delete[]
char * copyName()
{
char newname [256];
strcpy(newname, name);
return newname;
}
char * getName()
{return name;}
static void print(Base &base) //////////////////////使用引用
{printf("name: %s\n" , base.name);}
};
class Subclass : public Base
{
public:
Subclass(char * className) : Base(className)
{ }
};
int main()
{
Base * pBase = new Subclass("test");
Base::print(*pBase);
printf("name: %s\n", pBase->getName());
printf("new name: %s\n", pBase->copyName());
return 0;
}


修改的地方见程序的注释
长安宁 2008-11-24
  • 打赏
  • 举报
回复
Base(char * className)
{
name = new char[strlen(className)];
strcpy(name, className);
}
变成Base(char &className)

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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