CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
花落谁家,你作主! 盛大widget设计大赛英雄榜
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C++ Builder >  基础类

为什么我用c_str会出错的?(一定给分)

楼主wowboy(星仔)2001-05-19 19:32:00 在 C++ Builder / 基础类 提问

我在窗体上放了个edit控件  
  再放一个按钮,然后在BitBtn1Click中加入  
  char   *a;  
  a=Edit1->Text.c_str();  
  ShowMessage(a);  
  然后我运行后发现弹出的对话框只显示Edit,而Edit后的1不见了,我打Edit1rs还是只显示Edit,但我打Edit1rst就会全部都显示了.  
  这是为什么呢,请各位帮帮忙吧. 问题点数:30、回复次数:14Top

1 楼wowboy(星仔)回复于 2001-05-19 19:41:00 得分 0

还有我如果再加一个Label,然后把代码改为  
  char   *a;  
  a=Edit1->Text.c_str();  
  Label1->Caption=a;  
  ShowMessage(a);  
  结果会更神奇  
  我按一下按钮,label1上的显示是Edit1,对话框上的也是Edit1.  
  我再按一个按钮label1上显示的Edit后一个怪符号,对话框上的是Edit  
  但如果把ShowMessage(a);这一行去掉就什么事都没有了,这又是为什么呢?  
  Top

2 楼ALNG(?)回复于 2001-05-19 19:56:00 得分 0

不要存储AnsiString::c_str()的值,   TeamB   Guide.Top

3 楼ALNG(?)回复于 2001-05-19 19:58:00 得分 20

         
               
   
  --------------------------------------------------------------------------------  
   
   
  The   TeamB   guide   to   avoiding   common   mistakes   in   C++Builder.    
   
  Don't   store   the   result   of   AnsiString::c_str()    
   
  Examine   the   following   code   segment.    
   
          AnsiString   strText   =   "Howdy   Mr.   Ditka.";  
          char   *ptr   =   strText.c_str();  
          strText   =   "Goodbye   Mr.   Ditka";  
          Label1->Caption   =   ptr;  
   
  This   code   contains   a   serious   defect.   If   you   execute   this   code,   you   will   see   that   the   label   displays   the   first   string   that   was   assigned   to   strText.   This   may   surprise   you.   Why   doesn't   the   label   contain   the   string   that   says   "Goodbye   Mr.   Ditka"?   After   all,   doesn't   ptr   point   to   the   string   that   is   contained   in   the   strText   variable?    
   
  Whenever   you   assign   a   new   string   to   an   AnsiString   variable,   the   AnsiString   deallocates   whatever   memory   it   previously   owned   and   allocates   new   memory   for   the   new   string.   When   the   new   memory   is   allocated,   it   is   unlikely   to   be   the   same   memory   that   was   originally   returned   by   the   c_str   function.    
   
  The   second   line   of   code   in   the   example   above   stores   the   pointer   returned   by   c_str   for   later   use.   After   the   pointer   is   stored,   a   new   string   is   assigned   to   the   AnsiString   variable.   At   this   point,   the   strText   variable   deallocates   the   first   string   and   allocates   memory   for   the   new   string.   Now   ptr   points   to   memory   that   has   been   deleted.   When   you   copy   that   memory   into   the   label,   you   see   the   remnants   of   the   original   string.   For   larger   strings,   the   label   may   contain   garbage   characters,   or   the   label   may   appear   to   be   truncated.   De-referencing   the   data   in   the   ptr   variable   may   also   cause   an   access   violation   because   you   are   using   memory   that   the   application   no   longer   owns.    
   
  Storing   the   result   of   c_str   can   lead   to   problems   that   are   more   difficult   to   track   down.   For   example:    
   
          char   *ptr1   =   Edit1->Text.c_str();  
          char   *ptr2   =   Edit2->Text.c_str();  
   
          Label1->Caption   =   "Edit1   contains   "   +   AnsiString(ptr1);  
          Label2->Caption   =   "Edit2   contains   "   +   AnsiString(ptr2);  
   
  On   the   surface,   the   code   looks   like   it   should   work.   Sure,   we   store   the   pointer   returned   from   c_str,   but   nothing   is   done   that   would   cause   the   string   to   be   re-allocated   as   in   the   first   example.   However,   if   you   test   this   code,   you   will   see   that   it   does   not   work.   Sometimes   the   labels   will   both   display   the   string   from   the   second   edit   box,   and   sometimes   they   contain   garbage.    
   
  The   problem   is   that   the   Text   property   of   TEdit   returnes   a   new   AnsiString   by   value.   This   new   AnsiString   object   is   a   temporary   object.   Temporary   objects   don't   last   forever.   They   only   hang   around   as   long   as   they   are   needed.   They   are   destroyed   before   the   next   line   of   code   executes.    
   
  In   this   code   example,   the   temporary   object   is   only   needed   for   the   call   to   c_str.   Once   the   c_str   method   has   been   called,   the   temporary   object   is   destroyed   because   it   is   no   longer   needed.   Here   is   the   catch.   Deleting   the   temporary   object   deletes   the   memory   that   was   pointed   to   by   c_str,   which   means   that   ptr1   points   to   deleted   memory.   You   can   see   the   destruction   of   the   temporary   object   by   viewing   the   assembly   code   generated   by   these   statements.    
   
          //   assembly   output   for   the   statement  
          char   *ptr1   =   Edit1->Text.c_str();  
   
          mov       ...  
          lea       ...  
          call     System::AnsiString::AnsiString();   //   create   temp   object  
          mov       ...  
          inc       ...  
          mov       ...  
          call     Controls::TControl::GetText();         //   load   Caption   into   temp   AnsiString  
          lea       ...  
          call     System::AnsiString::c_str()               //   get   c_str   of   temp   object  
          mov       ...  
          dec       ...  
          lea       ...  
          mov       ...  
          call     System::AnsiString::~AnsiString       //   delete   temp   object  
   
  All   of   this   code   is   generated   by   the   one   statement   where   ptr1   is   assigned   the   value   of   Edit1->Text.c_str().   Before   the   next   line   of   code   executes,   the   temporary   AnsiString   object   is   destroyed.   Deleting   the   temporary   AnsiString   object   renders   the   previous   c_str   result   worthless,   and   that   is   exactly   what   happens   (and   it's   exactly   what   should   happen,   the   compiler   is   obeying   the   standard   by   cleaning   up   temporary   objects   in   this   manner).    
   
  The   moral   of   this   story   is   to   avoid   saving   the   result   from   AnsiString::c_str   because   you   run   the   risk   of   keeping   a   pointer   to   memory   that   has   been   de-allocated.    
   
     
  Top

4 楼cker(〖烟波浩淼三千里、人鬼殊途五百年〗)回复于 2001-05-19 21:23:00 得分 5

char   a[255];  
  strcpy(a,Edit1->Text.c_str());  
  ....Top

5 楼leejd(小东)回复于 2001-05-19 22:00:00 得分 0

同意楼上的,char类型的字符串只能用来拷贝的,不能直接赋值Top

6 楼songhtao(三十年孤独)回复于 2001-05-19 22:01:00 得分 0

我的正常Top

7 楼SAsura(爱我别走)回复于 2001-05-19 23:05:00 得分 5

ShowMessage接受的参数是AnsiString,为什么要转成char   *再传给他?  
  AnsiString::c_str()返回的指针只有暂时的意义  
  重分配字符串长度后地址很可能改变。Top

8 楼wowboy(星仔)回复于 2001-05-19 23:09:00 得分 0

我现在也正常了,但我平时见好多人都这么写的,难道都错了。  
  正如啊良说的用指针指向一个已释放的内存是个好大的漏洞。  
  那么我想问怎么平时见好多人都这么写的,都不对吗?  
  还有啊良,什么是TeamB   guide   好像蛮好的。Top

9 楼tlc97(文风)回复于 2001-05-19 23:19:00 得分 0

borland   的社区有很多这样的贴子Top

10 楼wowboy(星仔)回复于 2001-05-20 13:25:00 得分 0

我要把这个问题移回到CB版。Top

11 楼wowboy(星仔)回复于 2001-05-21 17:18:00 得分 0

给分.Top

12 楼comanche(太可怕)回复于 2001-05-21 17:36:00 得分 0

这样写没什么问题,但不知道你为什么这样???!!  
  TeamB是Borland   news   group   上一个著名小组,主要成员是   Borland公司VCL开发都和一些自愿的程序员(都很猛),不过跟他们交流后发现,原来他们也常放错..哈哈  
  Top

13 楼comanche(太可怕)回复于 2001-05-21 17:39:00 得分 0

楼上的   ALNG(GNLA)说得也没错,但关下面代码不正确的原因在  
          AnsiString   strText   =   "Howdy   Mr.   Ditka.";  
          char   *ptr   =   strText.c_str();  
          strText   =   "Goodbye   Mr.   Ditka";         //   这一句   AnsiString重新分配了内存,存                                  
                                                                              //   因为它比原来的大  
          Label1->Caption   =   ptr;  
   
  Top

14 楼wowboy(星仔)回复于 2001-05-26 18:13:00 得分 0

谢谢comanche(太可怕),可惜已经加分了^_^.  
  不过还是你感谢你的热心,下次给你加多点。  
  我的分数好少,所以。。。Top

相关问题

  • delete [] str出错!
  • C#中linklabel出错
  • FileStream.ReadBuffer(Str,n)出错!
  • 一定给分!!!我用VS.net生成C# WebProject出错!!!!急!
  • C#统计WORD表格中行列出错,高分求救。
  • c++builder6.0 启动出错
  • C++类出错问题;
  • C#静态方法出错????????????
  • 一段出错C代码
  • 分页出错??

关键词

  • code
  • ditka
  • ansistring
  • strtext
  • edit
  • mr
  • 对话框
  • goodbye
  • 按钮
  • showmessage

得分解答快速导航

  • 帖主:wowboy
  • ALNG
  • cker
  • SAsura

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo