用 C 语言指针操作字符串的时候,你是不是经常遇到报错?有时候明明觉得代码写得挺对,一运行就崩了,屏幕上可能跳出 “段错误”“访问冲突” 之类的提示,盯着代码看半天也找不出问题在哪。其实啊,指针操作字符串报错,多半是踩了几个常见的坑。今天兔子哥就给你掰扯掰扯这些原因,让你明白为啥会报错,一起往下看吧!
一、试着改字符串常量,能不报错吗?
你可能写过这样的代码:
c运行
char *str = "hello";str[0] = 'H'; // 这里一运行就报错为啥会这样?因为 "hello" 是字符串常量,它存放在内存的只读区域,就像图书馆里的书,你只能看不能涂画。指针 str 虽然指向了这个字符串,但你想通过它修改里面的内容,就像要在图书馆的书上改字,系统肯定不允许,不报错才怪。
那想改字符串咋办?可以用字符数组存字符串,比如:
c运行
char str[] = "hello"; // 这是数组,存放在可修改区域str[0] = 'H'; // 这样就没事了数组会把字符串复制一份到可修改的内存里,这时候随便改都没问题。
二、指针还没指向有效内存,就敢操作?
还有一种常见错误,指针定义了,但还没指向任何有效的字符串,就开始操作它。比如:
c运行
char *p;p[0] = 'a'; // 报错!p还没指向有效内存这时候的 p 就是个野指针,它指向的内存地址是随机的,可能是系统保护的区域,你往里面写东西,系统肯定会阻止,不报错才怪。
该咋办呢?得先让指针指向一块能用的内存,要么指向已有的数组,要么自己申请一块:
c运行
char arr[10];char *p = arr; // 指向数组,安全p[0] = 'a'; // 没问题// 或者自己申请内存char *q = malloc(10);q[0] = 'b'; // 也没问题,用完记得free(q)三、字符串越界了,还在使劲往后指
字符串都是以 '\0' 结尾的,如果你操作指针的时候,超过了这个范围,也会报错。比如:
c运行
char str[] = "hi"; // 实际存的是'h','i','\0',共3个字符char *p = str;*(p + 3) = 'a'; // 越界了!str只有3个元素,索引0-2这时候 p+3 已经超出了字符串的内存范围,可能指向了别的变量的内存,你往里面写东西,很可能破坏其他数据,系统检测到就会报错。
怎么避免?操作的时候心里得有数,知道字符串的长度,别让指针跑太远。可以用 strlen () 函数先算长度,比如:
c运行
int len = strlen(str);for (int i = 0; i < len; i++) { // 只循环到有效字符// 操作p+i}四、指针类型不对,能不捣乱吗?
有时候指针类型和字符串不匹配,也会出问题。比如用 int 类型的指针操作字符串:
c运行
int *p = "hello"; // 类型不匹配,虽然可能不报错*p = 'a'; // 操作时很可能出错int 指针一次操作 4 个字节(假设),而字符是 1 个字节,用 int 指针操作字符串,就像用大勺子舀小米,很容易碰坏旁边的东西,不报错才怪。
记住,操作字符串就得用 char 类型的指针,类型对了才能顺顺当当。
五、内存都释放了,还拿着指针瞎折腾
用 malloc 申请内存存字符串,用完释放了,但指针还留着,这时候再操作就麻烦了:
c运行
char *p = malloc(10);strcpy(p, "test");free(p); // 释放了内存*(p + 1) = 'a'; // 报错!内存已经还给系统了free 之后,p 指向的内存已经不属于你了,这时候再碰它,就像别人已经把房子收回去了,你还撬锁进去,肯定会被 “保安”(系统)拦住。
解决办法?free 之后马上把指针设为 NULL:
c运行
free(p);p = NULL; // 这样就算不小心操作了,也容易发现常见错误对比表,一看就明白
| 错误操作 | 错误原因 | 正确做法 |
|---|---|---|
| char *p = "abc"; p[0] = 'A'; | 修改字符串常量 | char p[] = "abc"; p[0] = 'A'; |
| char *p; p[0] = 'a'; | 指针未初始化 | char arr[10]; char *p = arr; p[0] = 'a'; |
| char str[] = "hi"; *(str+3) = 'x'; | 字符串越界 | 先算长度,不超过索引范围 |
| int *p = "abc"; *p = 'a'; | 指针类型不匹配 | char *p = "abc"; |
| free(p); p[0] = 'a'; | 释放后使用指针 | free(p); p = NULL; |
你可能会问,这些错误看着都挺简单,为啥还是老犯?其实啊,新手对内存的理解不深,总觉得指针就是个能随便指的东西,忘了它背后对应的内存有啥规矩。我以前也常犯,比如改字符串常量,第一次报错时还纳闷 “我明明就是改个字母啊”,后来才明白内存还有只读和可写之分。
兔子哥觉得,避免这些错误的关键,是记住指针只是个 “地址标签”,它本身不创造内存,也不决定内存能不能改。操作之前多问自己几句:这个指针指的内存能改吗?这块内存我能用吗?没超范围吧?多问几次,错的就少了。
其实指针操作字符串报错不可怕,每次错了都搞清楚原因,下次就不会再犯。练得多了,对内存的感觉就出来了,到时候用指针操作字符串,就像用筷子夹菜一样顺手。希望这些能帮到你,慢慢练,肯定能掌握!
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~