这种情况为什么会出现内存泄露

山伟 2010-01-20 10:42:38


typedef struct STRDESCRIPTION
{
string strInfo1;
string strInfo2;
string strInfo3;
}STRDESCRIPTION;

//定义结构体对象
STRDESCRIPTION m_oDescription;

//向结构体中赋值
void MyParser::characterDataHandler(const char *text, size_t len)
{
if(m_DCTag == DCTIT)
{
strncpy((char *)m_oDescription.strInfo1.c_str(),text,len);
}
else if(m_DCTag == DCCRE)
{
strncpy((char *)m_oDescription.strInfo2.c_str(),text,len);
}
else if(m_DCTag == DCSUB)
{
strncpy((char *)m_oDescription.strInfo3.c_str(),text,len);
}
}


上面的代码确实能够将text的内容传给结构体。但是现在出现了strInfo1正常,strInfo2也正常,strInfo3异常的情况。
通过跟踪发现在strInfo2拷贝完后strInfo3也已经有了值,分析内存地址后发现:原来strInfo2的地址是70538而strInfo3的地址是70558,也就说strInfo2只能存放32个字节,而strInfo2的长度超过32个后就放入strInfo3里,异常发生。

请问,我这样定义结构体为什么分配的内存是连续空间?
解决方法我知道是使用string的append函数,但是为什么不能使用strncpy对指针进行操作?
谁能帮我分析这样清楚产生的原因。
...全文
313 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
hai040 2010-01-21
  • 打赏
  • 举报
回复
看源码
山伟 2010-01-21
  • 打赏
  • 举报
回复
沉了。。。顶起来。
谁能谈谈string的实现?
山伟 2010-01-20
  • 打赏
  • 举报
回复
我现在的问题不是对string赋值,我想搞清楚声明一个string对象系统是如何对它进行分配空间及初始化的

1楼的大哥好像看明白我问什么了,但是请恕小弟愚笨。不是很清楚大哥表达什么意思。

哪位大人帮忙解惑下。
hai040 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 shanwei355 的回复:]
引用 6 楼 blackbillow 的回复:
太诡异了,你直接赋值不行?还少写很多代码:
m_oDescription.strInfo1 = text;


因为要截取text的len长,所以我使用strncpy。
好久没写过代码了,感觉已经不太会写了。所以写法可能比较诡异,一切都只为了实现。。。
别见怪!
[/Quote]
string::assign(text, len)
要不用copy也行
山伟 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 loaden 的回复:]
string类的成员内存布局类似:
class string
{
...
char* buf;
size_t length;
size_t cap;
size_t pos;
size_t other;
...
}
楼主明白为啥了么?
[/Quote]

请问,我上面出现的问题是不是和string的length有关?这里的length系统是如何定义长度的?
我跟踪代码后它为什么会分配连续的几段内存地址?
山伟 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 job82824 的回复:]
strncpy应该有返回值int的,楼主可以借助返回值来判断操作是否成功了。如果int!=len再用append不就行了?
[/Quote]

没必要,直接strInfo1.append(text,len);就可以赋值了。

job82824 2010-01-20
  • 打赏
  • 举报
回复
strncpy应该有返回值int的,楼主可以借助返回值来判断操作是否成功了。如果int!=len再用append不就行了?
dos5gw 2010-01-20
  • 打赏
  • 举报
回复
mark
wrf7729 2010-01-20
  • 打赏
  • 举报
回复
学习了
山伟 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 blackbillow 的回复:]
太诡异了,你直接赋值不行?还少写很多代码:
m_oDescription.strInfo1 = text;
[/Quote]

因为要截取text的len长,所以我使用strncpy。
好久没写过代码了,感觉已经不太会写了。所以写法可能比较诡异,一切都只为了实现。。。
别见怪!
老邓 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 loaden 的回复:]
string类的成员内存布局类似:
class string
{
...
char* buf;
size_t length;
size_t cap;
size_t pos;
size_t other;
...
}
楼主明白为啥了么?
[/Quote]
嗯,可能是我的表达的还不够清楚。
加个c_str()给楼主看看。

class string
{
char* c_str() const
{
return buf;
}

...
char* buf;
size_t length;
size_t cap;
size_t pos;
size_t other;
...
}
hlsoven 2010-01-20
  • 打赏
  • 举报
回复
弱弱的问下,怎么看内存的啊?想这些:strInfo2的地址是70538而strInfo3的地址是70558,
blackbillow 2010-01-20
  • 打赏
  • 举报
回复
太诡异了,你直接赋值不行?还少写很多代码:
m_oDescription.strInfo1 = text;
tan870426 2010-01-20
  • 打赏
  • 举报
回复
这样赋值感觉好不舒服...
hai040 2010-01-20
  • 打赏
  • 举报
回复
这不叫内存泄露
这是越界
用strcpy要保证目标地址空间足够

另外标准不知道有没规定c_str()返回的一定是原来的地址而不是副本
traceless 2010-01-20
  • 打赏
  • 举报
回复
怎么这样来操作string

string::c_str()返回类型是:const char *,
还有从没见过像这样来给string类型 赋值的

pengzhixi 2010-01-20
  • 打赏
  • 举报
回复
strInfo1.c_str(),//这个返回的是一个const对象 ,你转型后会产生临时对象的。所以最好不要这样做
老邓 2010-01-20
  • 打赏
  • 举报
回复
string类的成员内存布局类似:
class string
{
...
char* buf;
size_t length;
size_t cap;
size_t pos;
size_t other;
...
}
楼主明白为啥了么?
山伟 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 hh_xj 的回复:]
string内部对buf的管理属于实现细节,我们没必要去看它。

如果使用strcpy改变string对象,它的成功依赖于对string的实现的很多假设,这些假设未必总是成立。
比如, 一定要保证 strcpy 复制的由c_str返回的destbuf就是string用来存储字符串的buf,如果是,还要保证这段buf必须容纳len长度而不越界。看楼主的描述,很可能是buf越界,但strcpy不知道string的细节(实现),所以错误难免。

如楼主所说,一切为了实现,这句话我太欣赏了,我烦了的时候,这句话就是我的唯一思路指引。
[/Quote]

谢谢。
不过我现在就是想知道string的实现细节。
hh_xj 2010-01-20
  • 打赏
  • 举报
回复
string内部对buf的管理属于实现细节,我们没必要去看它。

如果使用strcpy改变string对象,它的成功依赖于对string的实现的很多假设,这些假设未必总是成立。
比如, 一定要保证 strcpy 复制的由c_str返回的destbuf就是string用来存储字符串的buf,如果是,还要保证这段buf必须容纳len长度而不越界。看楼主的描述,很可能是buf越界,但strcpy不知道string的细节(实现),所以错误难免。

如楼主所说,一切为了实现,这句话我太欣赏了,我烦了的时候,这句话就是我的唯一思路指引。
加载更多回复(1)

64,674

社区成员

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

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