Sus*_*ant 3 c++ string pointers
所以,它是一个非常简单的问题,我知道解决方案是一个简单的功能,如下所示:
void removeSpaces(char* s) {
char* source = s;
char* dest = s;
while(*source) {
if(*source == ' ') {
source++;
} else {
*dest++ = *source++;
}
}
*dest = 0;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Visual C++ 2008 Express版
当我用以下内容调用它时,它可以正常工作,没有任何问题,即它删除所有空格:
int main() {
char input[50] = "I like 2% milk";
removeSpaces(input);
cout<<input;
getchar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,问题是当我通过将字符串声明更改为此来调用它时:
char * input = "I like 2% milk";
Run Code Online (Sandbox Code Playgroud)
我得到一个例外(某种访问违规)
removeSpace函数的这行代码显示异常
*dest++ = *source++;
Run Code Online (Sandbox Code Playgroud)
任何人都可以详细说明为什么会发生这种情况?
当你这样做
char* something = "a string literal";
Run Code Online (Sandbox Code Playgroud)
编译器放入"a string literal"
可执行映像本身,只是为此内存分配一个指针something
.您不能修改此内存,并且很多时候字符串所在的内存标记为只读,因此任何写入它的尝试都会导致访问冲突,就像您遇到的那样.
当你这样做
char something[] = "a string literal";
Run Code Online (Sandbox Code Playgroud)
你真的在堆栈上创建一个名为something
并初始化它的数组"a string literal"
.这相当于做char something[] = {'a', ' ', 's', 't', 'r', ..., 'a', 'l', 0};
.由于此内存在堆栈中,您可以自由修改它.
char* something = "a string literal"
好像
stack executable
------------- ---------------------
|~~~~~~~~~~~| | ~~~~~~~~~~~~~~~~~ |
| something | -----------------> | a string literal0 |
------------- | ~~~~~~~~~~~~~~~~~ |
---------------------
Run Code Online (Sandbox Code Playgroud)
虽然char something[] = "a string literal"
看起来像
stack
-----
|~~~|
| a | <- something is an alias for this location
| |
| s |
| t |
| r |
| i |
| n |
| g |
| |
| l |
| i |
| t |
| e |
| r |
| a |
| l |
| 0 |
-----
Run Code Online (Sandbox Code Playgroud)
当~~~
意思是"其他内存等等".
注意
char* x = "string literal";
Run Code Online (Sandbox Code Playgroud)
实际上是无效的,不应该编译,因为你无法将a转换char const[x]
为a char*
.它应该是const char* x
,char* x
但不是,但一些旧的和不符合要求的编译器错误地允许这种行为.