郁闷啊!为什么BCB经常出现指针和内存错误?

软银云商包装 2004-08-03 10:36:48
在分析一个字符串的时候,我在定义了一个公共类,有如下函数:
char * __fastcall TBase::FilterString(char * str)
{
AnsiString s=str;
AnsiString aistr;
aistr= s.SubString(4,s.Length()-3 ) ;
char * bb=new char[aistr.length()+1];
strncpy(aistr.c_str(),bb,aistr.length()+1);
bb[aistr.length()+1]='\0';
return bb;

}
在其他文件中函数调用:
char * a="and b='cao'";
char * returns=FileterString(a);
ShowMessage(returns);

这段代码我测试了10多天了,一般情况下程序运行没有错误,但偶尔就会出错。
有时候我把char * a ="afaksfjksaiojewjiasdfasd00000" 之类的比较长的
字符串的时候就会有:acess vialotion 或者 pointer 之类的错误。记住,是有时候才会出错的。





...全文
242 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jim3 2004-08-06
  • 打赏
  • 举报
回复
我最近也出现指针操作错误的问题,后来发现就是因为操作字符串的时候越界导致的
比如:
AnsiString str = “hello”;
char * data ;
data = new char[str.Length()];
strcpy(data,str.c_str());

这段代码是有问题的,str.Length()是5,而strcpy拷贝的时候会拷贝6个字节,
多了一个\0',这段代码运行时可能不会有问题,也可能会出问题

所以楼主如果还没有解决问题的话,仔细检查自己的代码,尤其是内存操作的地方
还有就是打开CodeGuard进行检查
zihan 2004-08-06
  • 打赏
  • 举报
回复
搂主的这段代码我觉得设计上面就有问题了,你应该先delete了,然后重新写过,我觉得这样写很奇怪了.
myy 2004-08-06
  • 打赏
  • 举报
回复
yjy1001(蓝鲸--优秀得郁闷的鱼) 的写法的确不对。


我认为 此函数 参数 和 返回值 最好都用 AnsiString

AnsiString __fastcall TBase::FilterString(AnsiString str)
{
int len=str.Length();
if(len<4) return "";
return str.SubString(4,len-3);
}
CoolSoftBird 2004-08-06
  • 打赏
  • 举报
回复
返回指针肯定错误,
你要用引用作为参数
fangrk 2004-08-06
  • 打赏
  • 举报
回复
如果new了没有delete那么会造成内存泄漏,但不应该产生内存只读之类的错误

AnsiString __fastcall TBase::FilterString(const AnsiString& str)
{
int len=str.Length();
if(len<4) return "";
return str.SubString(4,len-3);
}
houing_0123 2004-08-06
  • 打赏
  • 举报
回复
注意new的东东一定要释放,还有需要new的东西,你没new,和同类的对象共同占有一段空间,你对一个释放了,但其他的对象就没有东西可指向了,也会出现类似的错误。这种错误要仔细的分析一下你代码的运行过程,单步运行,看看一些对象的值,你就会发现错在那里了!
houing_0123 2004-08-06
  • 打赏
  • 举报
回复
注意
cczlp 2004-08-06
  • 打赏
  • 举报
回复
实际不是BCB的错
jishiping 2004-08-06
  • 打赏
  • 举报
回复
不想谈楼主代码的效率和实际意义,改成如下就不会有 acess vialotion 的错误了。
char * __fastcall TBase::FilterString(char * str)
{
AnsiString s=str;
AnsiString aistr;
aistr= s.SubString(4,s.Length()-3 ) ;
char * bb=new char[aistr.length()+1];
strcpy(bb, aistr.c_str());
return bb;
}

这样,返回的 bb 是new出来的,这样返回没有任何错误。但是后面调用的代码,需要用
delete 删除这里的返回值。
magicsnake 2004-08-06
  • 打赏
  • 举报
回复

不是aistr.length()+1,而是:strlen(str)+1

aistr是被截断的字符串,该长度小于等于str的字符长度,
bb无论开的空间长度是aistr.length()+1还是strlen(str)+1,
在bb[aistr.length()+1]='\0';这个地方都会产生数组越界
houing_0123 2004-08-03
  • 打赏
  • 举报
回复
new了,不释放,会经常出现读地址错误,也就是内存错误的,我也出现过类似错误,身有感触!
Jim3 2004-08-03
  • 打赏
  • 举报
回复
楼上的代码我认为是有问题的

wuxq7311 2004-08-03
  • 打赏
  • 举报
回复
已知的就不用用NEW,很容易忘了DELETE!
yjy1001 2004-08-03
  • 打赏
  • 举报
回复
帮你改下
char * __fastcall TBase::FilterString(char * str)
{
AnsiString s=String(str);
AnsiString aistr;
if (s.Length < 3)
{
return NULL;
}

aistr = s.SubString(4,s.Length()-3 ) ;
return aistr.c_str();//不需要new出来,直接返回 就可以了
}

agan 2004-08-03
  • 打赏
  • 举报
回复
我这么认为:bb是局部变量,returns与bb指向同一内存区,但这时bb已经无效了,所以会出现指针错。
我建议:将该函数说明改为:void __fastcall TBase::FilterString(char * str,char * result)
ralpha08 2004-08-03
  • 打赏
  • 举报
回复
new了的用之后
一定要delete
软银云商包装 2004-08-03
  • 打赏
  • 举报
回复
我是楼主:
to yjy1001(蓝鲸--优秀得郁闷的鱼):
你的代码是行不通的,因为你返回的是在局部变量的地址,会出现字符串丢失的情况。

TO All:
我会delete 的,但我觉得如果char * 和 AnsiString 挂钩之后,就似乎不需要delete 了,
因为我如果delete a 就会出错。但我如果delete returns 就没事。我想bcb 的 AnsiString 应该已经动态处理内存了吧。

软银云商包装 2004-08-03
  • 打赏
  • 举报
回复
to jim3:
我的代码拷错了,不是aistr.length()+1,而是:strlen(str)+1
Jim3 2004-08-03
  • 打赏
  • 举报
回复
而且
bb[aistr.length()+1]='\0';
已经越界了,范围应该是0~aistr.length()
Jim3 2004-08-03
  • 打赏
  • 举报
回复
strncpy(aistr.c_str(),bb,aistr.length()+1);
这一句是不是写错了

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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