strcpy的越界问题

mengxiangying504 2008-12-05 06:53:29
void test1()
{
char string[10];
char* str = "0123456789";
strcpy(string, str);
std::cout << string << std::endl;
}

strcpy函数中while((*address++ = *strSrc++) != '\0'); address与strDest指向同一个地址,
那么上面的test1函数中在&string+1处的值不是改变成了'\0'了么?为什么不发生运行时错误?
...全文
243 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
mengxiangying504 2008-12-06
  • 打赏
  • 举报
回复
我问的问题是为什么数组越界了,却可以输出正确的结果...
mengxiangying504 2008-12-06
  • 打赏
  • 举报
回复
先改正一下“address与strDest指向同一个地址”,我写错,应该是*address和*strDest相等。

另外:我的程序运行是没有发生运行时错误的...何解
xxgamexx 2008-12-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 mengxiangying504 的回复:]
我问的问题是为什么数组越界了,却可以输出正确的结果...
[/Quote]

1,语言不对数组越界进行审查

2,你这里只是的破换了一个指向常量的指针(也就是 char* str = "0123456789";)
,并不构成什么太大的危险~

你可以试试破坏一个堆指针。


once_and_again 2008-12-06
  • 打赏
  • 举报
回复
The strncpy() function is similar, except that not more than n bytes of
src are copied. Thus, if there is no null byte among the first n bytes
of src, the result will not be null-terminated.
once_and_again 2008-12-06
  • 打赏
  • 举报
回复
The strcpy() function copies the string pointed to by src (including
the terminating ‘\0’ character) to the array pointed to by dest. The
strings may not overlap, and the destination string dest must be large
enough to receive the copy.
winingsky 2008-12-06
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wanfustudio 的回复:]
缺少保护意识。

|
|2.1 Memory Copy
| ex_1.
| char *p = MALLOC(10);
| MEMCPY(p, "123456789",9);
|
| p
| -----------------------------------------
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ? |
| -----------------------------------------
| ^ …
[/Quote]
UP!
NKLoveRene 2008-12-06
  • 打赏
  • 举报
回复
strncpy
bfhtian 2008-12-05
  • 打赏
  • 举报
回复
up ls
wangyaosuper 2008-12-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 SearchLife 的回复:]
void test1()
{
char string[10]; //应为char string[11];"0123456789"后有一个'\0'
char* str = "0123456789";
strcpy(string, str);
std::cout < < string < < std::endl;
}
[/Quote]

正解
飞哥 2008-12-05
  • 打赏
  • 举报
回复
缺少保护意识。

|
|2.1 Memory Copy
| ex_1.
| char *p = MALLOC(10);
| MEMCPY(p, "123456789",9);
|
| p
| -----------------------------------------
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ? |
| -----------------------------------------
| ^
| |
| p[9]
|
| if you do "STRLEN(p) = ?" are you sure it is 9?
|
| ex_2.
| char *p = MALLOC(10);
| MEMCPY(p, "1234567890",10);
|
| p
| -----------------------------------------
| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | ? | ? | ? |
| -----------------------------------------
| ^
| |
| p[9]
|
| if you do "STRLEN(p) = ?" are you sure it is 10?
|
| Solution:
| const int MAX_SIZE_FOR_THIS_EX 10
|
| char *p = MALLOC(MAX_SIZE_FOR_THIS_EX + 1); // 1 more room needed.
| MEMSET(, 0x0, MAX_SIZE_FOR_THIS_EX + 1); // set to zero for all
| MEMCPY(p, "123456789",MAX_SIZE_FOR_THIS_EX);// copy size
zxianrong 2008-12-05
  • 打赏
  • 举报
回复
其实是越界的吧,编译器的缘故,多给了两个CHAR ,长度定义为9也不错,8就错了。
xxgamexx 2008-12-05
  • 打赏
  • 举报
回复
1,address与strDest指向同一个地址

指向了同一地址???
怎么会?



2,&string+1 指向的应该是*str的栈地址。

而strcpy(string, str); 函数过后,破换了*str地址,导致程序会发生严重错误!

如下代码:


[root@localhost ~]# cat 1123.cpp && ./1123


#include <iostream>
#include <string.h>

int main()
{
char string[10];
char* str = "0123456789";
strcpy(string, str);
std::cout <<*(&string+1) << std::endl;
std::cout<<str<<std::endl;
return 0;
}


U��S���H����t�H�f���������u���[]���U��S��
[root@localhost ~]#


SearchLife 2008-12-05
  • 打赏
  • 举报
回复
void test1()
{
char string[10]; //应为char string[11];"0123456789"后有一个'\0'
char* str = "0123456789";
strcpy(string, str);
std::cout < < string < < std::endl;
}

子晞 2008-12-05
  • 打赏
  • 举报
回复
http://topic.csdn.net/t/20060416/14/4690289.html
机智的呆呆 2008-12-05
  • 打赏
  • 举报
回复
0字符的assic码是48
\0字符的是0怎么会是一样的?
找错题   试题1: void test1() {  char string[10];  char* str1 = "0123456789";  strcpy( string, str1 ); }   试题2: void test2() {  char string[10], str1[10];  int i;  for(i=0; i<10; i++)  {   str1[i] = 'a';  }  strcpy( string, str1 ); }   试题3: void test3(char* str1) {  char string[10];  if( strlen( str1 ) <= 10 )  {   strcpy( string, str1 );  } }   解答:   试题1字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;   对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;   对试题3,if(strlen(str1) <= 10)应改为if(strlen(str1) < 10),因为strlen的结果未统计’\0’所占用的1个字节。   剖析:   考查对基本功的掌握:   (1)字符串以’\0’结尾;   (2)对数组越界把握的敏感度;   (3)库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:   2分 void strcpy( char *strDest, char *strSrc ) {   while( (*strDest++ = * strSrc++) != ‘\0’ ); }   4分 void strcpy( char *strDest, const char *strSrc ) //将源字符串加const,表明其为输入参数,加2分 {   while( (*strDest++ = * strSrc++) != ‘\0’ ); }   7分 void strcpy(char *strDest, const char *strSrc) {  //对源地址和目的地址加非0断言,加3分  assert( (strDest != NULL) && (strSrc != NULL) );  while( (*strDest++ = * strSrc++) != ‘\0’ ); }   10分 //为了实现链式操作,将目的地址返回,加3分! char * strcpy( char *strDest, const char *strSrc ) {  assert( (strDest != NULL) && (strSrc != NULL) );  char *address = strDest;  while( (*strDest++ = * strSrc++) != ‘\0’ );   return address; } 从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!需要多么扎实的基本功才能写一个完美的strcpy啊!   (4)对strlen的掌握,它没有包括字符串末尾的'\0'。   读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为: int strlen( const char *str ) //输入参数const {  assert( strt != NULL ); //断言字符串地址非0  int len;  while( (*str++) != '\0' )  {   len++;  }  return len; }   试题4: void GetMemory( char *p )
本文的写作目的并不在于提供C/C++程序员求职面试指导,而旨在从技术上分析面试题的内涵。文中的大多数面试题来自各大论坛,部分试题解答也参考了网友的意见。   许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。企业要求面试者写一个最简单的strcpy函数都可看出面试者在技术上究竟达到了怎样的程度,我们能真正写好一个strcpy函数吗?我们都觉得自己能,可是我们写出的strcpy很可能只能拿到10分中的2分。读者可从本文看到strcpy函数从2分到10分解答的例子,看看自己属于什么样的层次。此外,还有一些面试题考查面试者敏捷的思维能力。   分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的深入剖析则可进一步增强自身的内功。   2.找错题   试题1: void test1() {  char string[10];  char* str1 = "0123456789";  strcpy( string, str1 ); }   试题2: void test2() {  char string[10], str1[10];  int i;  for(i=0; i<10; i++)  {   str1[i] = 'a';  }  strcpy( string, str1 ); }   试题3: void test3(char* str1) {  char string[10];  if( strlen( str1 ) <= 10 )  {   strcpy( string, str1 );  } }   解答:   试题1字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;   对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;   对试题3,if(strlen(str1) <= 10)应改为if(strlen(str1) < 10),因为strlen的结果未统计’\0’所占用的1个字节。   剖析:   考查对基本功的掌握:   (1)字符串以’\0’结尾;   (2)对数组越界把握的敏感度;   (3)库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:   2分 void strcpy( char *strDest, char *strSrc ) {   while( (*strDest++ = * strSrc++) != ‘\0’ ); }   4分 void strcpy( char *strDest, const char *strSrc ) //将源字符串加const,表明其为输入参数,加2分 {   while( (*strDest++ = * strSrc++) != ‘\0’ ); }   7分 void strcpy(char *strDest, const char *strSrc) {  //对源地址和目的地址加非0断言,加3分  assert( (strDest != NULL) && (strSrc != NULL) );  while( (*strDest++ = * strSrc++) != ‘\0’ ); }   10分 //为了实现链式操作,将目的地址返回,加3分! char * strcpy( char *strDest, const char *strSrc ) {  assert( (strDest != NULL) && (strSrc != NULL) );  char *address = strDest;  while( (*strDest++ = * strSrc++) != ‘\0’ );   return address; } 从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!需要多么扎实的基本功才能写一个完美的strcpy啊!   (4)对strlen的掌握,它没有包括字符串末尾的'\0'。   读者看了不同分值的strcpy版本,应该也可以写出一个10分的str

64,683

社区成员

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

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