24小时热门版块排行榜    

查看: 911  |  回复: 11
本帖产生 1 个 程序强帖 ,点击这里进行查看

江湖小白生

新虫 (初入文坛)

[求助] C++求助

#include
#include
using namespace std;
char *getname(void);
int main()
{
  char *name;
  name=getname();
  cout<   delete[] name;
  name=getname();
  cout<   delete[]name;
  return 0;
}
char *getname()
{
char temp[80];
cout<<"enter the name:";
cin>>temp;
char *pn=new char(strlen(temp)+1);
strcpy(pn,temp);
return pn;
}
回复此楼

» 猜你喜欢

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

江湖小白生

新虫 (初入文坛)

运行结果是这样



2楼2011-11-04 11:10:10
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

ioadong

木虫 (著名写手)

【答案】应助回帖


xzhdty(金币+1): 欢迎常来程序语言讨论 2011-11-04 22:25:58
char *getname()
{
char temp[80];
cout<<"enter the name:";
cin>>temp;
char *pn=new char(strlen(temp)+1);//这里分配了局部指针
strcpy(pn,temp);
return pn;//这里返回这个指针,但是在函数返回后,这个变量的生命期已经结束了。
}

这个函数返回了在堆中分配的临时指针pn。楼主好好看看教材上关于指针用法的注意点吧。
以科学的理性代替天然的非理性。
3楼2011-11-04 14:58:23
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

sudo

木虫 (正式写手)

引用回帖:
3楼: Originally posted by ioadong at 2011-11-04 14:58:23:
char *getname()
{
char temp[80];
cout<<"enter the name:";
cin>>temp;
char *pn=new char(strlen(temp)+1);//这里分配了局部指针
strcpy(pn,temp);
return pn;//这里返回这个指针 ...

这个解释是不对的~你搞混了栈和堆
4楼2011-11-04 15:37:29
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

sudo

木虫 (正式写手)

【答案】应助回帖


xzhdty(金币+1): 谢谢参与 2011-11-04 22:26:38
问题在于
CODE:
char *pn=new char(strlen(temp)+1);

应该是
CODE:
char *pn=new char[strlen(temp)+1];

这两种写法,第二种才是申请一段内存。第一个仅仅申请了一个char的内存,然后内容初始化为strlen(temp)+1的值而已。
5楼2011-11-04 15:39:51
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

ioadong

木虫 (著名写手)

【答案】应助回帖

引用回帖:
4楼: Originally posted by sudo at 2011-11-04 15:37:29:
这个解释是不对的~你搞混了栈和堆

你再看看那个错误提示框中的内容。清清楚楚的"heap buffer"
你说的是另外一个问题,即指针越界的问题,但这不是出现图中错误对话框的原因。
我特地复习了一下,new分配的变量一般都是在堆空间的。
以科学的理性代替天然的非理性。
6楼2011-11-04 16:32:57
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

sudo

木虫 (正式写手)


jjdg(金币+1): 感谢参与 2011-11-04 23:41:44
引用回帖:
6楼: Originally posted by ioadong at 2011-11-04 16:32:57:
你再看看那个错误提示框中的内容。清清楚楚的"heap buffer"
你说的是另外一个问题,即指针越界的问题,但这不是出现图中错误对话框的原因。
我特地复习了一下,new分配的变量一般都是在堆空间的。

the application wrote to memory after end of heap buffer.
就是写越界了

刚才说的你混淆了堆和栈,说的是有关“生命期”的理解的问题。
char *getname()
{
char temp[80];
cout<<"enter the name:";
cin>>temp;
char *pn=new char(strlen(temp)+1);//这里分配了局部指针
//虽然pn是局部指针,但是对于堆里面的内存,如果不delete掉或者进程结束,将一直处于“有生命”的状态
strcpy(pn,temp);
return pn;//这里返回这个指针,但是在函数返回后,这个变量的生命期已经结束了。
//嗯,虽然pn的生命期确实已经结束,但是,它的值指向的内存块的生命期还在
}
7楼2011-11-04 17:04:26
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

sudo

木虫 (正式写手)

【答案】应助回帖

★ ★
余泽成(金币+2, 程序强帖+1): 谢谢参与应助! 2011-11-10 21:44:28
引用回帖:
6楼: Originally posted by ioadong at 2011-11-04 16:32:57:
你再看看那个错误提示框中的内容。清清楚楚的"heap buffer"
你说的是另外一个问题,即指针越界的问题,但这不是出现图中错误对话框的原因。
我特地复习了一下,new分配的变量一般都是在堆空间的。

再来看看这个问题是怎么产生的,VC在debug模式下进行编译的时候,使用的delete会调用crt\src\dbgheap.c里面的这个函数:
CODE:
/***
*int _CrtCheckMemory() - check heap integrity
*
*Purpose:
*       Confirm integrity of debug heap. Call _heapchk to validate underlying
*       heap.
*
*Entry:
*       void
*
*Return:
*       TRUE - if debug and underlying heap appear valid
*       FALSE otherwise
*
*******************************************************************************/
extern "C" _CRTIMP int __cdecl _CrtCheckMemory(void);

然后,会在delete的时候,对堆进行一个详细的检查,其中有一段是这样的:
CODE:
if (!CheckBytes(pbData(pHead) + pHead->nDataSize, _bNoMansLandFill,
                nNoMansLandSize))
                {
                    if (pHead->szFileName)
                    {
                        _RPT5(_CRT_WARN, "HEAP CORRUPTION DETECTED: after %hs block (#%d) at 0x%p.\n"
                            "CRT detected that the application wrote to memory after end of heap buffer.\n"
                            _ALLOCATION_FILE_LINENUM,
                            blockUse,
                            pHead->lRequest,
                            (BYTE *) pbData(pHead),
                            pHead->szFileName,
                            pHead->nLine);
                    }
                    else
                    {
                        _RPT3(_CRT_WARN, "HEAP CORRUPTION DETECTED: after %hs block (#%d) at 0x%p.\n"
                            "CRT detected that the application wrote to memory after end of heap buffer.\n",
                            blockUse, pHead->lRequest, (BYTE *) pbData(pHead));
                    }
                    okay = FALSE;
                }

它使用CheckBytes发现了写在了申请到的堆内存空间范围的后面,然后就给程序员报了个_CRT_WARN。

以上~
8楼2011-11-04 17:08:52
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

sudo

木虫 (正式写手)


余泽成(金币+1): 鼓励交流! 2011-11-10 21:44:39
嗯借此机会了解一下不同编译器在debug下,编译程序时加入的一些检查手法也大有裨益~

不同编译器的做法是不同的哦。比如g++的话,楼主可能会发现没有什么报错之类的,但是这也不能说明程序是正确的。

-.<总之还是建议不要太教条主义(这里不是否定标准的重要性),学会使用调试工具是很有必要的
9楼2011-11-04 17:15:51
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

sudo

木虫 (正式写手)


jjdg(金币+1): 感谢参与 2011-11-04 23:41:58
再啰嗦一下过程吧:

写越界发生在strcpy,然后发现的时间是在delete调用_CrtCheckMemory后~
10楼2011-11-04 17:20:01
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 江湖小白生 的主题更新
信息提示
请填处理意见