返回static的变量指针危险和printf的执行顺序
2012-03-16 09:47
337 查看
char* fun(const char* src) { static char dest[32] = ""; strcpy(dest, src); return dest; } int main(int argc, char* argv[]) { char s1[32] = ""; char s2[32] = ""; strcpy(s1, fun("hello")); strcpy(s2, fun("world")); printf("%s %s\n", s1, s2); printf("%s %s\n", fun("hello"), fun("world")); getchar(); }
上文在vs2008的执行结果如下
hello world
hello hello
从以上结果可以看出
1.printf函数从右执行
2.返回static变量的指针有点危险。值则不会有这个问题。
上面的这段代码确实不能看,字符串复制,不需要传入长度参数,也不根据结束符判断大小,也无法确定是否会溢出。不可取,不可取。
我们在写C/C++程序的时候,经常需要从调用函数中取得自己想要的数据,这就需要调用者和函数之间要有个内存的交互,我们通常采用的方法是传递一个指针给被调函数,作为被调函数的输出参数,这也是我们常用的、规范的做法。
但有很多程序员比较习惯直接取返回值,这就面临一个问题就是普通局部变量都是在栈上分派的,会随着函数的结束而弹栈释放,那么就会出现返回局部变量数组的问题,这时有人会想到用malloc或new在堆上分派内存,没错,这样是避免了前面说的问题,但这样又会带来新的问题,就是需要在外部对这块内存进行释放,这个是比较难把握的,多次释放会出现程序的crash,忘记释放了会出现内存leak,所以这种方法也不被推荐。还有人想到了更另类的方法,就是上面例子中的static类型,没错,static变量也是全局的,但就会出现上面程序的运行结果(可以认为不是我们想要的结果,也就是错误的结果)。
所以,我们要慎用返回函数内部的static内存的这种设计,但如果在无法改变设计模式的情况下(有些系统函数的实现,比如inet_ntoa,可以通过在man手册中看到这样的一句话:The string is returned in a statically allocated buffer,
which subsequent calls will overwrite),那么在自己使用的时候一定要注意,不要试图保存返回的内存地址或引用,而要保存返回内存的内容,也就是例子程序中的strcpy两行。
inet_ntoa的错误使用(判断两个IP地址是否相等):
1
struct in_addr addr1;
2
struct in_addr addr2;
3
4
// 网络包中包含了源地址
5
addr1.s_addr = 0x6500A8C0 // 192.168.0.101
6
addr2.s_addr = 0x6600A8C0 // 192.168.0.102
7
8
// 这个if语句将永远为真
9
if (strcmp(inet_ntoa(addr1), inet_ntoa(addr2)) == 0) {
10
// do something
11
} else {
12
// do other thing
13
}
看官笑过,出差回来水一篇
相关文章推荐
- Java中的static变量、方法、代码块初始化执行顺序
- 构造函数初始化、static代码块初始化、成员变量初始化、以及在子父类中混合的执行顺序实例
- 静态加载顺序,类static变量也有默认值(不同于C++),普通成员变量直接赋值语句和非静态语句块的执行位置
- 返回本地变量的指针是很危险的
- Java中static成员变量、成员变量、static代码块、代码块、构造方法的执行顺序
- 当函数的参数中包括变量,而又想在函数执行时,改变该变量的值,使其返回,应该用指针
- java变量,初始化快,构造函数的执行顺序
- Jquery ajax执行顺序 返回自定义错误信息
- 或操作(||)和与操作(&&)的执行顺序以及返回结果
- java 中try catch finally 的具体执行顺序返回结果+代码测试
- JS的预编译和执行顺序 详析(及全局与局部变量)
- C指针以及为什么不能返回局部指针变量,却可以返回局部变量
- 第二天 引用 命令执行顺序 变量
- C++函数中的static变量初始化及析构顺序
- Java父类与子类中静态代码块 实例代码块 静态变量 实例变量 构造函数执行顺序
- Java初始化顺序总结及其程序执行过程图- 静态变量、静态代码块、成员变量、构造函数
- static 块以及代码块执行顺序
- static、非static执行顺序以及super
- 不要返回指向局部变量的指针
- c笔记08---变量,栈,秒表练习,关键字 static,指针变量和变量的指针