返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C/C++返回内部静态成员的陷阱有哪些
  • 283
分享到

C/C++返回内部静态成员的陷阱有哪些

2023-06-17 13:06:21 283人浏览 八月长安
摘要

这篇文章主要介绍“C/C++返回内部静态成员的陷阱有哪些”,在日常操作中,相信很多人在C/c++返回内部静态成员的陷阱有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C/C++返回内部静态成员的陷阱有哪些

这篇文章主要介绍“C/C++返回内部静态成员的陷阱有哪些”,在日常操作中,相信很多人在C/c++返回内部静态成员的陷阱有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C/C++返回内部静态成员的陷阱有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

在我们用C/C++开发的过程中,总是有一个问题会给我们带来苦恼。这个问题就是函数内和函数外代码需要通过一块内存来交互(比如,函数返回字符串),这个问题困扰和很多开发人员。如果你的内存是在函数内栈上分配的,那么这个内存会随着函数的返回而被弹栈释放,所以,你一定要返回一块函数外部还有效的内存。

这是一个让无数人困扰的问题。如果你一不小心,你就很有可能在这个上面犯错误。当然目前有很多解决方法,如果你熟悉一些标准库的话,你可以看到许多各式各样的解决方法。大体来说有下面几种:

1)在函数内部通过malloc或new在堆上分配内存,然后把这块内存返回(因为在堆上分配的内存是全局可见的)。这样带来的问题就是潜在的内存问题。

因为,如果返回出去的内存不释放,那么就是memory Leak。或者是被多次释放,从而造成程序的crash。这两个问题都相当的严重,所以这种设计方法并不推荐。(在一些windows api中,当你调用了一些API后,你必需也要调用他的某些API来释放这块内存)

2)让用户传入一块他自己的内存地址,而在函数中把要返回的内存放到这块内存中。这是一个目前普遍使用的方式。很多Windows API函数或是标准C函数都需要你传入一个buffer和这个buffer的长度。这种方式对我们来说应该是屡见不鲜了。这种方式的好处就是由函数外部的程序来维护这块内存,比较简显直观。但问题就是在使用上稍许有些麻烦。不过这种方式把犯错误的机率减到了***。

3)第三种方式显得比较另类,他利用了static的特性,static的栈内存一旦分配,那这块内存不会随着函数的返回而释放,而且,它是全局可见的(只要你有这块内存的地址)。所以,有一些函数使用了static的这个特性,即不用使用堆上的内存,也不需要用户传入一个buffer和其长度。从而,使用得自己的函数长得很漂亮,也很容易使用。

这里,我想对第三个方法进行一些讨论。使用static内存这个方法看似不错,但是它有让你想象不到的陷阱。让我们来用一个实际发生的案例来举一个例子吧。

示例

有过Socket编程经验的人一定知道一个函数叫:inet_ntoa,这个函数主要的功能是把一个数字型的IP地址转成字符串,这个函数的定义是这样的(注意它的返回值):

char *inet_ntoa(struct in_addr in);

显然,这个函数不会分配堆上的内存,而他又没有让你传一下字符串的buffer进入,那么他一定使用“返回static char[]”这种方法。在我们继续我们的讨论之前,让我们先了解一下IP地址相关的知识,下面是inet_ntoa这个函数需要传入的参数:(也许你会很奇怪,只有一个member的struct还要放在struct中干什么?这应该是为了程序日后的扩展性的考虑)

struct in_addr {  unsigned long int s_addr;  }

对于IPV4来说,一个IP地址由四个8位的bit组成,其放在s_addr中,高位在后,这是为了方便网络传输。如果你得到的一个s_addr的整型值是:3776385196。那么,打开你的Windows计算器吧,看看它的二进制是什么?让我们从右到左,8位为一组(如下所示)。

11100001 00010111 00010000 10101100

再把每一组转成十进制,于是我们就得到:225 23 16 172, 于是IP地址就是 172.16.23.225。

好了,言归正传。我们有这样一个程序,想记录网络包的源地址和目地地址,于是,我们有如下的代码:

struct in_addr src, des;  ........  ........  fprintf(fp, "源IP地址<%s>\t 目的IP地址<%s>\n", inet_ntoa(src), inet_ntoa(des));

会发生什么样的结果呢?你会发现记录到文件中的源IP地址和目的IP地址完全一样。这是什么问题呢?于是你开始调试你的程序,你发现src.s_addr和des.s_addr根本不一样(如下所示)。可为什么输出到文件的源和目的都是一样的?难道说是inet_ntoa的bug?

src.s_addr = 3776385196; //对应于172.16.23.225  des.s_addr = 1678184620; //对应于172.16.7.100

原因就是inet_ntoa()“自作聪明”地把内部的static char[]返回了,而我们的程序正是踩中了这个陷阱。让我们来分析一下fprintf代码。在我们fprintf时,编译器先计算inet_ntoa(des),于是其返回一个字符串的地址,然后程序再去求inet_ntoa(src)表达式,又得到一个字符串的地址。

这两个字符串的地址都是inet_ntoa()中那个static char[],显然是同一个地址,而第二次求src的IP时,这个值的des的IP地址内容必将被src的IP覆盖。所以,这两个表达式的字符串内存都是一样的了,此时,程序会调用fprintf把这两个字符串(其实是一个)输出到文件。所以,得到相同的结果也就不奇怪。

仔细看一下inet_ntoa的man,我们可以看到这句话:The string is returned in a statically allocated buffer, which subsequent calls will overwrite. 证实了我们的分析。

到此,关于“C/C++返回内部静态成员的陷阱有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: C/C++返回内部静态成员的陷阱有哪些

本文链接: https://lsjlt.com/news/289201.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C/C++返回内部静态成员的陷阱有哪些
    这篇文章主要介绍“C/C++返回内部静态成员的陷阱有哪些”,在日常操作中,相信很多人在C/C++返回内部静态成员的陷阱有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C/C++返回内部静态成员的陷阱有哪些...
    99+
    2023-06-17
  • C++类的静态成员有哪些
    本篇内容介绍了“C++类的静态成员有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在静态成员函数的实现中不能直接引用类中说明的非静态成员...
    99+
    2023-06-17
  • 学习C++静态成员的注意事宜有哪些呢
    这篇文章将为大家详细讲解有关学习C++静态成员的注意事宜有哪些呢,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。下面着重介绍C++静态成员,类的静态数据成员应该在代码中被显示的初始化,一定要在...
    99+
    2023-06-17
  • C语言的使用陷阱有哪些
    这篇文章主要讲解了“C语言的使用陷阱有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言的使用陷阱有哪些”吧!1. 正确理解函数声明你是否见过这样的代码“(*(void(*)())0)...
    99+
    2023-06-16
  • C++的static静态成员你有了解吗
    目录一、静态成员二、静态成员变量三、静态成员函数四、访问静态成员的方式五、小结六、静态成员必须在定义类的文件中对静态成员变量进行初始化七、什么能在类内初始化八、C++静态类型成员变量...
    99+
    2024-04-02
  • C++类与对象深入之静态成员与友元及内部类详解
    目录一:静态成员1.1:静态成员分类1.2:静态成员变量1.3:静态成员函数1.4:总结特性1.5:试题示例1.6:C++11成员初始化新玩法二:友元2.1:全局函数做友元2.2:类...
    99+
    2024-04-02
  • C++ 元编程的最佳实践和常见陷阱有哪些?
    元编程是一种编译时代码操作技术,提供了代码通用化、高效化、易维护等优点。最佳实践包括隔离元编程代码、使用类型安全、清晰命名、单元测试和文档化。常见陷阱有可扩展性问题、调试困难、维护挑战、...
    99+
    2024-05-21
    c++ 元编程
  • java单例静态内部类的优点有哪些
    Java单例静态内部类的优点包括:1. 延迟加载:通过静态内部类的方式创建单例对象,只有当第一次使用时才会加载内部类。这样可以在多线...
    99+
    2023-10-11
    java
  • C#中静态变量与非静态变量的区别有哪些
    这篇文章主要为大家展示了“C#中静态变量与非静态变量的区别有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C#中静态变量与非静态变量的区别有哪些”这篇文章吧。静态变量:静态变量使用 stat...
    99+
    2023-06-17
  • C++类的默认成员函数有哪些
    本文小编为大家详细介绍“C++类的默认成员函数有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++类的默认成员函数有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。类的默认成员函数每个类中,如果不主动实...
    99+
    2023-06-29
  • c语言静态变量的特点有哪些
    C语言中的静态变量具有以下特点:1. 生命周期长:静态变量在程序运行期间始终存在,不会随着函数的调用而销毁。它们的值在函数调用之间保...
    99+
    2023-09-14
    c语言
  • C++ 静态函数的性能考虑有哪些?
    静态函数性能考虑如下:代码大小:静态函数通常更小,因为不包含成员变量。内存占用:不属于任何特定对象,不占用对象内存。调用开销:更低,无需通过对象指针或引用调用。多线程安全:通常线程安全,...
    99+
    2024-04-16
    性能 c++ 静态函数 内存占用
  • C++ 静态函数的使用场景有哪些?
    静态函数在 c++++ 中用于与类无关的操作或实用程序功能,包括:效用函数:提供独立的实用程序功能,如字符串操作或数学运算。工厂方法:创建类的新实例,返回指针或引用。常量函数:访问常量数...
    99+
    2024-04-16
    c++ 静态成员函数 作用域
  • java成员内部类的注意事项有哪些
    1. 成员内部类不能有静态成员(静态字段、静态方法),除非静态成员是final和static的常量。2. 成员内部类可以访问外部类的...
    99+
    2023-09-26
    java
  • c++函数返回引用的情况有哪些
    C++函数返回引用的情况有以下几种: 返回左值引用:函数可以返回已存在的变量、类成员或者数组的引用。例如: int& getVar...
    99+
    2023-10-23
    c++
  • C++ 中函数的返回值类型有哪些?
    c++++ 中函数的返回值类型定义了执行后返回的值的类型:基本类型:void(不返回值)、bool、整数、浮点、字符引用类型:类型引用、类型指针结构体或类:类型实例 C++ 中函数的返...
    99+
    2024-04-12
    c++ 返回值类型
  • c语言中静态变量的特点有哪些
    C语言中静态变量的特点有以下几点:1. 静态变量的作用域仅限于定义它的函数内部,但是其在函数调用结束后仍然存在,保留其值,下次调用时...
    99+
    2023-09-14
    c语言
  • java静态内部类实现单例的好处有哪些
    Java静态内部类实现单例的好处包括:1. 懒加载:静态内部类只有在使用时才会被加载,因此能够实现延迟加载的效果。这种方式不会在单例...
    99+
    2023-10-12
    java
  • C++ 函数返回值的优化技巧有哪些?
    c++++ 函数返回值优化技巧:直接返回变量:避免创建局部变量副本。返回引用:避免返回值赋值操作。返回右值引用:避免临时对象额外复制。使用移动语义:实现移动构造函数和赋值运算符,避免不必...
    99+
    2024-04-11
    c++ 函数返回值优化
  • C++ 函数的返回值类型有哪些选择?
    c++++ 函数的返回值类型指定了函数调用的结果类型。可用的返回值类型包括:基本类型:int、float、double、char、bool自定义类型:结构、类、联合void(不返回任何值...
    99+
    2024-04-19
    函数 c++ 返回值类型
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作