请教个关于数组越界的结构体

unhappyless 2008-05-31 08:28:41
就下面的代码能正常运行,但如果把 ss 字符串再加一字符就异常了,为什么?我只是用 dump.p 来保存指针为什么会出错?

#include <string.h>
#include <iostream>
using namespace std;
struct dump
{
int id;
char p[1];
};
int main()
{
string ss = "0123456789abcd";
int size = sizeof(dump);
dump* pdump = ( dump*)malloc(size);//+ strlen("0123456789abcd")+1);
strcpy(pdump->p ,ss.c_str());
cout<<pdump->p<<endl;
int b=9;
cout<<b<<endl;
}
...全文
403 54 打赏 收藏 转发到动态 举报
写回复
用AI写文章
54 条回复
切换为时间正序
请发表友善的回复…
发表回复
花花呀123456 2008-06-04
  • 打赏
  • 举报
回复
哈哈,我也来看看热闹!
taodm 2008-06-04
  • 打赏
  • 举报
回复
[Quote=引用 48 楼 fuqd273 的回复:]
引用 47 楼 unhappyless 的回复:
但大师也明显是给 char[1] 的空间里放了很大的值,虽然后面有很大的空间来容纳,但这么写很安全吗?


恩,不安全。
over
[/Quote]
兄弟,累了吧。
fuqd273 2008-06-04
  • 打赏
  • 举报
回复
[Quote=引用 47 楼 unhappyless 的回复:]
但大师也明显是给 char[1] 的空间里放了很大的值,虽然后面有很大的空间来容纳,但这么写很安全吗?
[/Quote]

恩,不安全。
over
unhappyless 2008-06-04
  • 打赏
  • 举报
回复
但大师也明显是给 char[1] 的空间里放了很大的值,虽然后面有很大的空间来容纳,但这么写很安全吗?
xjy1204 2008-06-04
  • 打赏
  • 举报
回复
这是什么代码...汗..
讨论这么久有意义么?
fuqd273 2008-06-04
  • 打赏
  • 举报
回复
兄弟,别人的做法和你的做法有本质区别。
让在下给你详细的解释下:

对于inside the c++ object model 里面的代码,他申明了,需要在系统内存中使用sizeof(struct mumble ) + strlen(string) + 1那么大的内存,然后将这块内存的首地址赋值给struct mumble类型的指针变量pmumble。这块内存整体是足以放下strcpy(pmumble->pc, string ) ;里面的string的。

而对于你的代码,你只是申明了sizeof(struct mumble )大小的内存,系统会将处在这块内存后另作他用,或者运气好,系统没有使用这块内存之后的连续内存。但是,结果是一样的,在你进行strcpy(pdump->p ,ss.c_str());操作之后,因为字符串ss的大小超过了你事先申明占用的系统内存的大小,于是溢出了。

溢出,是对已分配的内存来说的。
inside the c++ object model 里面的代码,虽然是将分配好的内存作为struct mumble类型的指针处理的,但是实际上已分配的内存的大小不是struct mumble构造体的大小。

人家的代码,在进行通信协议解析的时候,是很常用的方法。
楼主对指针、内存的概念需要加深理解。
unhappyless 2008-06-04
  • 打赏
  • 举报
回复
那照 42 楼的说法,大师的代码也是溢出了,只不过他后面有足够的空间给他溢出。
不解,大师为什么要这么写。这样异常安全吗?
tjltail 2008-06-04
  • 打赏
  • 举报
回复
c,c++是不检查内存越界情况的,但是操作系统会检查,现在操作系统一般都是用页式管理
当你越界要求换页的时候,操作系统会报错。

你多加几个字符会出错,可能刚好导致它换页,可能在运行下又没有事情了。
再者windows的页默认为64k,假如恰好你内存分配在页首,恭喜你你可以越界64K,假如在页尾,哪么一个字符都不行。

越界范围为[0,64k)
fuqd273 2008-06-04
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 unhappyless 的回复:]
int size = sizeof(dump);
dump* pdump = ( dump*)malloc(size);//+ strlen("0123456789abcd")+1);

struct mumble* pmumble = (struct mumble* ) malloc (sizeof(struct mumble ) + strlen(string) + 1);

差别就是在被我注释的部分,但就按照 Inside C++ object 里的代码也溢出了。为什么大师要这么写代码?
[/Quote]

恰恰就是这点区别,造成了你的程序溢出了,而他的没有。
星光伴月 2008-06-04
  • 打赏
  • 举报
回复
呵呵呵呵,你以为蚂蚁真的能怀上大象的孩子?!
taodm 2008-06-04
  • 打赏
  • 举报
回复
那我反问一个:
假如存在这么一个平行宇宙,在那里
dump* pdump = ( dump*)malloc(size);//+ strlen("0123456789abcd")+1);
这么申请内存将导致后面的memcpy发生内存溢出
struct mumble* pmumble = (struct mumble* ) malloc (sizeof(struct mumble ) + strlen(string) + 1);
这么申请内存后面的memcpy不发生内存溢出,没有安全忧患。

那么,你能给出“内存溢出”的定义,让上面成立么?
unhappyless 2008-06-04
  • 打赏
  • 举报
回复
[Quote=引用 49 楼 taodm 的回复:]
引用 48 楼 fuqd273 的回复:
引用 47 楼 unhappyless 的回复:
但大师也明显是给 char[1] 的空间里放了很大的值,虽然后面有很大的空间来容纳,但这么写很安全吗?


恩,不安全。
over

兄弟,累了吧。
[/Quote]

呵呵,不好意思,比较喜欢追究下去哈
luhongyu2108 2008-06-03
  • 打赏
  • 举报
回复
不同编译器对溢出的处理不一样
Kevin0602 2008-06-03
  • 打赏
  • 举报
回复
错误太多
myhuochai 2008-06-03
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 kokiahuang 的回复:]
程序根本就是错误的,通过char p[1];声明的p只能存储一个字符,但是出于对齐分配了4个字符。
strcpy(pdump->p ,ss.c_str()); 不知道楼主这句话是什么意思,根本就没有为pdump->p分配空间。
估计楼主是想这样:
C/C++ code
#include <string.h>
#include <iostream>
using namespace std;
struct dump
{
int id;
char *p; //modify here
};
int main()
{
string ss = "0123456789abcd";
int size = sizeof(dum…
[/Quote]

这个是正解!!(楼主的代码错得离谱,根本不值得去运行)
unhappyless 2008-06-03
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 taodm 的回复:]
引用 16 楼 taodm 的回复:
dump* pdump = ( dump*)malloc(size);//+ strlen("0123456789abcd")+1);

一样么?
认真点呀。
[/Quote]

差不多吧
strcpy(pmumble->pc, string ) ; 看出 string 是个 const char* 因为在 C 中没有 string 这类型

还有为什么大家老说没分配内存,有这必要吗?


dump* pdump = ( dump*)malloc(size);//+ strlen("0123456789abcd")+1);
上面这句不就分配内存了,只是把内存分配和对象构造分开而已
strcpy(pdump->p ,ss.c_str());
Lstyk 2008-06-03
  • 打赏
  • 举报
回复
struct mumble* pmumble = (struct mumble* ) malloc (sizeof(struct mumble ) + strlen(string) + 1);

struct mumble* pmumble = (struct mumble* ) malloc (sizeof(struct mumble ));
多申请了strlen(string) + 1的空间。
作用与26楼说的差不多。

楼主发的帖子中的代码没有分配足够的空间,
strcpy(pdump->p ,ss.c_str());内存溢出了,没有报错不是说没有错误,而是碰巧pdump->p指向的内存空间起始地址向后有足够的空间存放ss.c_str()。
unhappyless 2008-06-03
  • 打赏
  • 举报
回复
struct mumble 
{
char pc[1];
};

struct mumble* pmumble = (struct mumble* ) malloc (sizeof(struct mumble ) + strlen(string) + 1);
strcpy(pmumble->pc, string ) ;



上面是大师的代码
fuqd273 2008-06-03
  • 打赏
  • 举报
回复
你确定按照他写的代码也溢出了么?
怎么确定的?
你的证据是什么?使用什么工具?怎么观察到的?


unhappyless 2008-06-03
  • 打赏
  • 举报
回复
int size = sizeof(dump);
dump* pdump = ( dump*)malloc(size);//+ strlen("0123456789abcd")+1);

struct mumble* pmumble = (struct mumble* ) malloc (sizeof(struct mumble ) + strlen(string) + 1);

差别就是在被我注释的部分,但就按照 Inside C++ object 里的代码也溢出了。为什么大师要这么写代码?

加载更多回复(34)

64,637

社区成员

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

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