2 rainbow forever rainbow_forever 于 2015.07.05 16:41 提问

c++ new 的用法的问题
c++

char*p=new char[2];//p指针是指向一个两个字符长度的指针
strcpy(p,"asd");
cout<<p
结果输出是asd,p指针不是只指向含有含有两个字符的之真忙,为什么还能输出asd

8个回答

caozhy
caozhy   Ds   Rxr 2015.07.05 16:51

strcpy不会检查缓冲区长度,所以它不安全,应该废弃它,使用strncpy,它会根据你提供的长度截断字符串,避免超长。

oyljerry
oyljerry   Ds   Rxr 2015.07.05 17:26

strcpy就是buffer overflow的一个源头,因为它会导致拷贝超过长度数据。可以用strncpy或者windows上面用strncpy_s。这个更安全。

91program
91program   Ds   Rxr 2015.07.05 21:19

strcpy(p,"asd"); 在此段代码中会引起内存操作的越界。
小范围的越界,可能不会引起严重的问题。但越界后,会引起程序中其它变量数值的变化。如果影响的变量是一个指针,再后续对此指针操作时可能会引起错误导致程序异常退出。】

C语言,指针是十分强大的,但 C 语言不对指针做越界判断的。

frank_20080215
frank_20080215   2015.07.05 17:48

strcpy不会检测长度,用strcpy函数

tabe123
tabe123   Rxr 2015.07.05 18:10

在vs上,strcpy函数会报错,会建议strcpy_s();

cuidashen
cuidashen   2015.07.05 23:03

首先你是用了new动态分配的函数,动态分配内存时会在首地址的后边空出一大片内存区域,strcpy()函数不检查越界。如果你是用free()函数将动态内存释放后,你会发现p的值还在,一直到这片内存被其他变量覆盖时,p的值才改变。这就是动态分配内存的特点。

zuishikonghuan
zuishikonghuan   2015.07.06 22:53

那是因为当前读写的虚拟内存页面的访问规则是运行读写的,Windows(以Windows为例,你可以理解为我只会Windows上的)为虚拟内存的每一个页面设置了一个访问规则,我们知道应用程序访问的内存永远是4G的虚拟内存,而且只有一半的空间(2G)可以用,系统只允许内核程序访问物理内存(例如驱动可以这么做,但实际上,很少有驱动会访问物理内存),因此对于每个进程而言,a进程的一个内存地址所在页面和b进程的同样地址所在页面被系统映射到了不同的物理内存(分页内存在条件满足的时候系统会酌情映射到磁盘上),系统会为每一个虚拟内存页面设置一个“虚拟内存访问规则”,也就是“内存虚拟保护”,访问规则包括读(read),写(write),让CPU执行代码(execute),这三种规则可以自由组合(应用程序可以使用VirtualProtect这个API修改指定页面的虚拟内存访问规则),当一个程序访问了它不该访问的内存时,会产生“虚拟内存违规访问”,从而导致程序崩溃(在xp下就非常人性化的弹出xxx程序在xxx处指令访问的xxx内存,此内存不能为“read/write”),而我上面也说了,访问规则是对于一个内存页面而言的,一个页面应该有4k(如果我没记错),而你的p指针指向的位置只要不倒霉到指向了页面的尾部,那么即使超出了字符串,只要没超出这个页面,就不会发生虚拟内存违规访问,因此不会出现问题,当然,有可能损坏其他数据而引发未定义的行为

down_load_111
down_load_111   2015.07.05 17:38

strcpy不会检测长度,换一种吧

Csdn user default icon
上传中...
上传图片
插入图片