看一下这几行代码有什么问题,很简单超不过5行,在不同的电脑上调试过几十遍

muzhuagang 2003-09-26 12:01:26
#include<iostream>
main()
{
char mu[2];
cout<<"please you name:"<<endl;
cin<<mu;
cout<<"you name is "<<mu;
}
执行的时候,如过输入6个以下的字符,没问题,如果输入6个以上的字符,退出时会出错,已经在不同的电脑上调试过几十遍
...全文
32 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiminggw 2003-09-27
  • 打赏
  • 举报
回复
up
panzhaoping 2003-09-27
  • 打赏
  • 举报
回复
侯捷在<<more effective c++>>中说,写出这样代码的
只能是少理,大家不必多和他废话
sad_4978 2003-09-27
  • 打赏
  • 举报
回复
我觉得你要是在c++中编程的话可以用string,这个数据类型。比char要强很多。
danielhf 2003-09-26
  • 打赏
  • 举报
回复
这种程序是浪费时间, 它的结果本身是未定义的, 作实验没有任何意义,它取决与越界以后的内存空间是作什么用的.
cgsw12345 2003-09-26
  • 打赏
  • 举报
回复
cin<<mu;是不是寫錯了啊.(cin>>mu;)
1cs1ak1 2003-09-26
  • 打赏
  • 举报
回复



没有出错,只能说你还比较幸运。
这种是不确定的。也许越界,也许非法访问,也许死机。


Andy84920 2003-09-26
  • 打赏
  • 举报
回复
[linuxsir@ecit ch06]$ ./zhao
Your name: zhaoxiang
Your name is zhaoxiang
Segmentation fault


看.如果输入超过你的数组长度.出现这样.

Segmentation fault
tonybaobao 2003-09-26
  • 打赏
  • 举报
回复
这样可以规定读取的字节数:
const int size = 2;
char array[ size ];
cin.getline(array,size);
zhusunme 2003-09-26
  • 打赏
  • 举报
回复
在#include<iostream>之后加using namespace std;
cin<<mu;应该是cin>>mu;
scuthdd 2003-09-26
  • 打赏
  • 举报
回复
char mu[2]改过这句话没有啊????
tonybaobao 2003-09-26
  • 打赏
  • 举报
回复
晕,你之分配了2个字节,还想输入那么多?已经给你赚拉!
muzhuagang 2003-09-26
  • 打赏
  • 举报
回复
刚才大家的回答我都看了,说些无聊或其它的我就不在这里说了,有一,二两位地却是高手的回答,我在这里谢了,
wizlian 2003-09-26
  • 打赏
  • 举报
回复
我来说两句,造成这种结果的主要原因要涉及到变量的分配原理,他分配时是4个字节,4个字节的分配。最后的’\0’是输入回车加的
所以你输入后,其实分配给你的有4个空间,所以输入不超过4个字节都不会报错的
如我改一下你的程序
#include <iostream>
#include <stdlib.h>

int main()
{
char mu[5];
std::cout<<"please you name:"<<std::endl;
std::cin>>mu;
std::cout<<"you name is "<<mu<<std::endl;

system("PAUSE");
return 0;
}
此时你完全可以输入8个而没有得不到错误的信息
wolfyang 2003-09-26
  • 打赏
  • 举报
回复
我觉得站着说话的人不嫌腰疼

cin输入符串的时候没有长度检查,需确保使用cn.width()函数来规定最
大缓冲大小.所以你输多少都会接收
看看下面文章吧


v安全编程详解v1.00

翻译:By xundi@xfocus.org --> 此原文是来自www.securityfocus.com中的Secure Programming v1.0,本人建

议能读原文读原文,如果你英语实在不过关,就读此文吧,并且感谢你能花不少时间来看这篇我敲了很长时间

的文章。
--------------------------------------------------------------------------------
0.0 目的

1.0 一般情况
1.1 缓冲溢出

1.1.1 strcpy
1.1.2 strcat
1.1.3 sprintf
1.1.4 gets
1.1.5 scanf, sscanf, fscanf
1.1.6 memcpy
1.1.7 C++

1.0 一般情况
这部分章节讨论的安全编程技术可以同时应用于UNIX和WINDOW操作系统,涵盖的主题可以在多种语言和操作系

统的得到应用,这些技术能在绝大多数计算机上应用的编程的定例和概念。

1.1 缓冲溢出

至今为止最通常的一种安全漏洞—缓冲溢出在今天的用种应用程序中存在,不过这个问题不是新问题,相反它

在前10年前就存在于一些操作系统和应用程序,而1近10年来此类型问题的发现和在重要软件上被利用的频率飞

快的增加,这不是问题不存在,而在于这种攻击的理念的性质而不被以前多数用户感兴趣,今天随着极具机械

式的怎样利用这些问题的教育和一些可以说“异端“人的增加,导致使用个技术简单话。
此部分目的不是描述怎样挖掘一个有缓冲溢出的漏洞,而是理解这种类型问题的重要性和运行这种程序会导致

怎样的严重后果。
缓冲溢出出现在当一些数据拷贝到内存区域中产生,如果内存的缓冲区不能够容纳这些数据,到拷贝成功的时

候,目标内存的边界部分就会被覆盖。程序中的变量可以被在程序栈(stack)中也可以在程序堆(heap)中,

因此我们也可以常听到这些字汇,栈溢出和堆溢出,相比较这两个溢出类型,栈溢出的利用多数情况下会比较

容易点。
让我们看看一段存在缓冲溢出错误的源代码:
void function(char *str)
{
char buffer[16];
strcpy(buffer,str);
}

void main()
{
char large_string[256];
int i;

for( i = 0; i < 255; i++)
large_string[i] = 'A';

function(large_string);
}
在上面的程序中,func()函数拷贝一有255字节组成的字符串到只有16字节大小的缓冲中,并且由于使用了

strcpy()而没有检查字节数,这样你编译运行这个程序的话,运行的时候将导致段冲突。
255个字符串拷贝到缓冲区时,缓冲在开头16个字节填充后就被填满,这样,多出来的字符串将覆盖堆栈中的其

他变量,包括函数的返回地址,这返回地址是指当前函数返回时程序所需继续执行的内存地址,通过修改这个

地址,攻击者可让程序在不同的位置后续执行,而如果在刚才递交给缓冲中的数据带有指令代码,且被覆盖的地

址又切切指向这段代码,此代码就会被执行.
通过使用strncpy()函数代替,就能比较安全的拷贝字符串,因为它只会将大小同目标缓冲区的数据拷贝.
现在许多有缓冲溢出倾向的函数都存在相对安全的副本函数,它们都通过传递大小参数来限制多少数据被调用

 strcpy() 此函数没有执行任意长度的确认,而使用strncpy()函数可以限制长度,当使
用strncpy()的时候,你需要含蓄地以NULL终结字符串,因为有NULL终
止符暗示定义源缓冲区的大小

不正确情况 正确的情况

void func(char *str) void func(char *str)
{ {
char buffer[256]; char buffer[256];
strcpy(buffer, str); strncpy(buffer, str, sizeof(buffer) -1);
return; return;
} }

strcat() 此函数类似与strcpy(),也不检查字符串的长度,使用strncat()可以很好的限制
被拷贝的长度,strncat()函数只会追加定义在大小参数中的长度,NULL终止符将终止字
符串.

不正确情况 正确的情况

void func(char *str) void func(char *str)
{ {
char buffer[256]; char buffer[256];
strccat(buffer, str); strncat(buffer, str, sizeof(buffer) -1); return; return;
} }

sprintf() 此函数用来格式化字符串变量,是很容易产生缓冲溢出的地方,前几个月出现
过很多严重的缓冲溢出,如wuftp,就是使用了这个函数的缘故.使用snprintf()
可以很好的限制拷贝到缓冲中的打印数据长度,snprintf()函数返回要传递过
去的数据字符总数,如果它大于能传递字节大小的值,那么没有任何数据写到
缓冲中,用户必须检查snprintf()的值以保证要被打印的缓冲.

不正确情况 正确的情况

void func(char *str) void func(char *str)
{ {
char buffer[256]; char buffer[256];
sprintf(buffer,”%s”, str); if (snprintf(target, sizeof(target) - 1, "%s", return; string) >

sizeof(target) - 1)
} /* 缓冲发生 */
return;
}
gets 此函数天生就存在漏洞,你在应用程序中应该永远不要使用,一般在你编译的时候
也会被警告,gets()没有规定任意长度,永远将导致缓冲溢出,它从标准输入中读取数
据并一直到换行符或者EOF标识接收到,所读的数据全部填充到定义的缓冲,并不
检查任何长度.

不正确情况 正确的情况

void func(char *str) void func(char *str)
{ {
char buffer[256]; char buffer[256];
gets(buffer, str); fgets(buffer, sizeof(buffer) –1,stdin);
return; return;
} }
而上面的fgets()函数用来代替不安全的gets()函数,此函数会至多读取’sizeof(buffer) – 1’
的文件流 .当然你中途读取到EOF或者换行符也会停止.

scanf(), 在使用这些函数的时候你需要小心读取要放到固定长度缓冲区的数据,你须确保规sscanf(), 定要读

到缓冲区的数据长度,下面很好的演示了有问题和安全的两个版本:
fscanf()
有漏洞的版本 安全的版本
char buffer[256]; char buffer[256];
int num; int num;
num = fscanf(stdin, "%s", buffer); num = fscanf(stdin, "%255s", buffer);
你可以看到上面安全的那个示例,规定了只能读取255个字符到规定的缓冲中,如果类似
上面所示第一个示例,就会无限制的读取,并导致函数的堆栈被破坏.

Memcpy() 由于不安全的使用memcpy()会导致不少溢出,当规定了长度的memcpy()函数
可以受外界操作的时候,就可能发生,所以保证拷贝到内存结构中的数据不大于
规定大小将非常重要,下面一个示例将说明缓冲是怎样产生的:
unsigned long copyaddress(struct hosten *hp) {
unsigned long address;

memcpy(&address, hp->h_addr_list[0], hp->h_length);
}
上面的示例来自与一个出现在BIND (Berkeley 网路名字守护程序)上的实际
漏洞,在这里我们为了教育目的简单花了,上面的函数拷贝hp->h_length字节
到’address’变量中(4字节),在正常情况下, 因为是网路地址hp->h_length一般
都是4字节,但是,攻击者确可以操作利用h_length变量,如果他伪造一个假
的DNS回应,他就可以提供更长的地址通过hp-h_addr_list变量传递,这将导致
超过4个字节大小拷贝到’address’变量,溢出变量,拷贝多的数据到堆栈.

所以你确保在执行这种操作前检查长度,如:

unsigned long copyaddress(struct hosten *hp) {
unsigned long address;

if (hp->h_length > sizeof(address))
return 0;

memcpy(&address, hp->h_addr_list[0], hp->h_length);

return address;
}
此漏洞在BIND系统中已经修补.
C++ C++语言存在一些独特的额外的问题,如下面的例子会导致程序产生缓冲溢出,极类
似C中的gets()函数.
char buf[128];
cin >> buf;
上面函数中在读字符串的时候没有长度检查,需确保使用cn.width()函数来规定最
大缓冲大小.

skiffer 2003-09-26
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include<iostream>
using namespace std;
main()
{
char mu[2];
cout<<"please you name:"<<endl;
cin>>mu;
cout<<"you name is "<<mu;
}
dlmsexyf 2003-09-26
  • 打赏
  • 举报
回复
嗯!
bing_huo 2003-09-26
  • 打赏
  • 举报
回复
char si[2];
问题就在这了 楼上的几位说的很清楚了。。
muzhuagang 2003-09-26
  • 打赏
  • 举报
回复
#include <iostream.h>
对不起,写错了,应该这样写:
#include <stdlib.h>
int main()
{
char si[2];
cout<<"pleae you string:"<<endl;
cin>>si;
cout<<"the si is "<<si;
system("PAUSE");
return 0;
}
执行的时候,如过输入6个以下的字符,没问题,如果输入6个以上的字符,退出时会出错,已经在不同的电脑上调试过几十遍
liao2001 2003-09-26
  • 打赏
  • 举报
回复
好久没吃辣子鸡丁了,广州的菜真是差
Jinhao 2003-09-26
  • 打赏
  • 举报
回复
楼主真厉害!!
加载更多回复(1)
[为什么要学习Spring Cloud微服务] SpringCloud作为主流微服务框架,已成为各互联网公司的首选框架,国内外企业占有率持续攀升,是Java工程师的必备技能。就连大名鼎鼎的阿里巴巴dubbo也正式更名为Spring Cloud Alibaba,成为了Spring Cloud 微服务中的一个子模块。Spring Cloud是企业架构转型、个人能力提升、架构师进阶的不二选择。 【推荐你学习这门课的理由】 1、本课程总计29课时,从微服务是什么、能够做什么开始讲起,绝对的零基础入门 2、课程附带全部26个项目源码,230页高清PDF正版课件 【课程知识梳理】 1、先讲解了什么是单体架构、什么是微服务架构、他们之间有什么区别和联系,各自有什么优缺点。 2、从本质入手,使用最简单的Spring Boot搭建微服务,让你认清微服务是一种思想和解决问题的手段,而不是新兴技术。 3、讲解Spring Boot 与Spring Cloud 微服务架构之间的联系,原生的RestTemplate工具,以及Actuator监控端点的使用。4、带着微服务所带来的各种优缺点,为大家引入服务发现与注册的概念和原理,从而引入我们的第一个注册中心服务Eureka。5、引入负载均衡的理念,区分什么是服务端负载均衡,什么是客户端负载均衡,进而引入Ribbon负载均衡组件的详细使用。6、为了解决微服务之间复杂的调用,降低代码的复杂度,我们引入了Feign声明式客户端,让你代码搞定服务的远程调用。7、最后为大家介绍了整个微服务体系应该包含什么,学习路线是什么,应该学习什么。 【学习方法】 每一节课程均有代码,最好的方式是静下心来,用一天的时间,或者两个半天时间来学习。一边听我的讲解,一边使用我提供的项目代码观察和运。只要你能跟住我的节奏,你就可以搞定微服务。

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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