我无法理解为什么这段代码会导致未经处理的访问违规行为"例外。这是一个简单的程序,试图将一个字符串指针字符串复制到另一个字符串,同时跳过一些字符(索引处的字符:3,4,5)
#include <conio.h>
#include <iostream>
using namespace std;
void main()
{
char str[20];
char *str1 = "abcdeabcde", *str2 = "";
int i, dx = 0;
for(i=0; *(str1+i)!='\0'; i++)
if(i<3 || i>5)
{
*(str2 + dx) = *(str1 + i);
dx++;
}
*(str2+dx) = '\0';
cout<<str2;
_getch();
}
使用语法*(str + i)
的赋值在以下函数代码中工作正常(它是getline的实现)
int getstr(char *str, int n)
{
char ch;
int i = 0;
for(i=0; i<n && (ch = _getch())!= '\r'; i++)
{
if(ch == '\b')
{
if(i == 0)
{
i = -1; continue;
}
else
{
cout<<"\b \b";
i -= 2;
}
}
else if(ch > 31 && ch < 127 && i<n-1)
{
cout<<ch;
*(str + i) = ch;
}
else
{
cout<<"\a";
i--;
}
}
*(str + i) = '\0';
return i+1;
}
那么为什么这会在第二种情况下起作用而不是在第一种情况下呢?
答案 0 :(得分:3)
那么为什么这会在第二种情况下起作用而不是在第一种情况下呢?
因为在第一种情况下,这些是文字字符串char *str1 = "abcdeabcde", *str2 = "";
,您不能更改str1
和str2
的内容
这是C / C ++中众所周知的未定义行为。请参阅此列表:What are all the common undefined behaviours that a C++ programmer should know about?
特别是这一行:
答案 1 :(得分:2)
这就是你的问题:
*(str2 + dx) = *(str1 + i);
str2
是指向字符串文字的指针。只要您没有读过它的NUL字符,就可以从str2
读取,但是不允许您在其中写入,因为编译器可能会将字符串文字存储在您的特定且只读部分中二进制的。
在这里,你写到str2
结束。这是一个双重未定义的行为!