转自:http://www.typecodes.com/cseries/trimspace0xC0000005.html
在c/c++中,有时会遇到 c0xC0000005: 读取/写入位置冲突的问题。明明编译器编译通过,但是在执行的时候就出现 Segmentation fault(coredump) 了。该错误是由于内存访问出错引起的,最常见于指针的错误使用和数组越界等。下面是博主之前的一个经历——去掉一个字符串前后的所有空格。
char * pcontent = " abcdef "; //待去掉前后空格的字符串
char * p = NULL;
/* 1去除后面的空格 */
p = pcontent + strlen( pcontent ) - 1; //指针p指向字符串的末尾
while( *p == 0x20 )
{
p--;
}
*(p+1) = 0x00; //将字符串中‘f’后面的一位空格改成结束符号'\0'
printf( "Line=[%d], pcontent=[%s]\n", __LINE__, pcontent );
咋一看,思路挺对的,遍历字符串后面的所有空格,然后只要将字符串中‘f’后面的一位空格改成字符串结束符即可。遗憾的是出现了 Segmentation fault(coredump) ,用Vs调试,程序执行到断点 *(p+1) = 0x00; 时,出现未经处理的异常: 0xC0000005 写入冲突。
调用内存和堆栈可以看到地址 0x001b5764 里面的元素是 0x20,表示空格。
为什么把字符串结束符号'\0'写入到地址 0x001b5764 中就出错呢?原因是:定义指针pcontent的时候,语句 char * pcontent = " abcdef " 中的字符串是一个常量 " abcdef "。常量在内存中是不可以被改写的,所以执行 *(p+1) = 0x00; 就会出现 未经处理的异常: 0xC0000005: 写入位置冲突 。
另外,对于内存中的 0x00000000 地址,不能执行读取和写入操作。例如前面的 char * p = NULL; 这种指针初始化(避免成为野指针)操作,在后面不能直接来一个 printf("%c", *p) ,否则就会出现错误 未经处理的异常:0xC0000005:读取位置0x00000000时发生冲突 。
知道原理后,改成正确的去掉一个字符串前后的所有空格的程序:
/**
* @FileName : trimallspace.c
* @Author : vfhky http://www.typecodes.com 20140725
* @Functions: 去掉字符串前后所有的空格
*/
#include <string.h>
#include <stdio.h>
int main()
{
char * p = NULL;
char ccontent[20] = " abcdef "; //把字符串放进一个数组而不是成为常量
printf( "Line=[%d], ccontent=[%s]\n", __LINE__, ccontent );
/* 1去除后面的空格 */
p = ccontent + strlen( ccontent ) - 1;
while( *p == 0x20 )
{
p--;
}
*(p+1) = 0x00;
printf( "Line=[%d], pcontent=[%s]\n", __LINE__, p );
/* 2去除前面的空格 */
p = ccontent; //重置指针变量p的位置
while( *p == 0x20 )
{
p++;
}
printf( "Line=[%d], p=[%s]\n", __LINE__, p );
return 0;
}