一级指针易错情况
一 char*字符串做函数参数
二 字符数组越界
三 修改了指针p指向的地址,又printf打印指针p指向的变量,或者想用free(p)去释放刚开始malloc的内存
一 char*字符串做函数参数:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void copy_str(char *from, char *to)
{
if (*from == '\0' || *to == '\0')
{
printf("function copy_str error \n");
return;
}
for (; *from != '\0'; from++, to++)
{
*to = *from;
}
*to = '\0'; //手动补充字符串结尾符
}
void main()
{
char *p = NULL;
char to[100];
copy_str(p, to);
system("pause");
return;
}
如上代码,可以放到编译器里运行下,是会直接崩掉的。为什么呢?
因为 copy_str函数里的判断if (*from == '\0' || *to == '\0')。 形参from是指针,存储这指向的变量的内存地址,*from是指针from指向的变量的值。为什么这么判断直接崩溃了?
因为我们没有保证from指针不为NULL就用*去取指针指向的变量了。
正确的方法是if(from == NULL || to == NULL)去判断指针是否为空。
然后再看是否判断需要判断指针指向的内容为'\0',再去判断*from == '\0'的情况
二 字符数组越界:
char buf[5] = "Hello"; 对于字符串,编译器会自动加'\0'为Hello\0,导致数组越界
三 修改了指针p指向的地址,又printf打印指针p指向的变量,或者想用free(p)去释放刚开始malloc的内存:
所以,不要随便改变形参的值。记得用个临时的指针变量char *tmp = p;去指向p指向的地址。后面改变tmp的地址即可。
四 向函数外传递临时变量的地址:
char *str_cnct(char *x, char *y)
{
char str3[20];
char *p = str3; //指针p指向数组的起始地址
return p;
}
上面的代码中str3是str_cnct函数里的局部变量,存储在栈区,str_cnct函数执行结束后,str3的内存被回收了,return p把数组的地址返回给调用函数。
使用该内存地址时候可能该位置存放的是别的变量的地址。