- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我注意到我想对有关指针和变量的问题进行解答,这并不是真正的问题,但我想了解详细信息。简而言之,为了绕过使用全局变量,我已经开始让函数返回指向函数内部数据的指针。有时,该数据需要是静态的,而其他时候则不是。
例如,假设我有一个函数,该函数创建2d char数组,并在其中填充“ a”并返回指向该数组的指针。当调用者尝试使用该指针访问和修改2d数组所在的内存时,将出现随机数据,而不是2d数组的内容。我发现将2d数组声明为static可以解决此问题,因为该数组的内容保存在其作用域之外。
现在,另一方面,我有一个声明结构的函数,并使用值对其进行初始化。然后,该函数返回指向该struct变量的指针。尝试通过指针访问结构的值时,调用方应该具有无意义的数据,但有趣的是,没有。我认为就像在2d数组的情况下一样,在函数调用之后,由于struct不是静态的,因此应该释放该内存中的数据。但是,事实并非如此,尽管它不是静态的,但我可以通过指针访问所有结构的元素。
总体而言,在函数完成之后,只要该数据是静态的(在2d数组情况下),调用方就可以访问和修改在该函数中创建的变量的数据,但是有时变量的数据会保留在范围之外,即使不是标记为静态(结构用例)。为什么?
最佳答案
您对在char
或struct
的二维数组中出现的数据的观察在函数返回后是否持续存在,是偶然的结果,而不是C标准定义的行为,您可能不依赖它们。它们仅仅是C编译器在特定情况下的行为的产物。在其他情况下,它们可能会更改,并且可能无法依赖。
每当您提供要在函数返回后使用的对象时(例如通过返回指向该对象的指针),该对象都不得具有自动存储期限。它可以具有静态存储持续时间,分配的存储持续时间或线程存储持续时间。
首先,让我们澄清一些术语。这对于理解概念很重要。 C标准不使用术语“全局变量”。它通常不使用“变量”来描述对象,也根本不使用“全局”来描述对象。在C标准中,您认为变量是标识符和对象。标识符是对象的名称,而对象是可以表示值的数据存储区。
C标准是否保证某个对象可以在特定时间使用取决于对象的生存期。生存期是指在程序执行期间对象存在于C语言的计算模型中。生命周期部分取决于其存储持续时间。存储时间取决于定义或创建对象的方式和位置。
寿命还受对象标识符范围的影响。范围是在源代码中可见(可以使用)标识符的位置。范围和生存期之间存在关系,但是它们是截然不同的东西。
有四个存储期限(还有一个特殊的临时存储期限,我将不在这里讨论):
如果使用_Thread_local
声明标识符,则其对象具有线程存储持续时间。它的生命周期从创建线程开始,到线程执行结束时结束。因此,只要函数的线程仍在执行,就可以在函数返回后使用它。
否则,如果使用static
或extern
或在函数参数的任何块或列表之外(实际上在任何函数之外)声明标识符,则其对象具有静态存储持续时间。它存在于整个程序执行过程中,因此在执行过程中可以随时使用。
否则,对于对象的任何标识符(而不是类型定义,函数等),其对象具有自动存储期限。它与在其中声明的语句块相关联。(一个块是括号内的一系列语句,{ ... }
。这可以是定义函数或嵌套在其中的块的主要块。)其寿命在执行时结束关联的块末端。 C标准不能保证在块的执行结束后尝试使用自动对象时会发生什么。
请注意,当函数调用子例程时,该函数的执行(包括其中的块)会暂时挂起,但不会结束。 (当函数返回时,执行结束,或者调用了诸如abort
,exit
或longjmp
之类的特殊例程。)这意味着在执行子例程时该对象仍然存在。即使子例程中的源代码的作用域与调用函数的作用域不同,也是如此。
由于上述原因,声明您不能使用超出其范围的对象的语句是错误的。范围不是确定是否可以访问对象的决定因素。终生是。
对于第四个存储期限:
具有分配的存储持续时间的对象由malloc
,calloc
,realloc
和aligned_alloc
创建,并且没有名称(标识符)。分配的对象从分配的时间扩展到释放的时间。因此,如果函数分配了一个对象并返回指向该对象的指针,则该指针可用于访问该对象,直到释放该对象为止。
关于c - 返回指针时,什么时候数据需要是静态的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57565355/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 5 年前。 Improve
在 C# 静态方法中是否有一种方法可以引用定义该方法的类型? 在实例方法中,您可以通过以下方式确定类型: public void Foo() { Type type = this.GetTyp
WPF:静态、动态资源以及资源词典 静态资源与动态资源 我们常常会使用样式或者控件模板放在Window.Resources中,比如这样: 静态资源与动态资源使用如下: <Window
任何人都知道如何在共享/静态函数中动态加载控件?该函数本身位于 mustinherit/abstract 类中。 (这是 VB 中的 ASP.NET 项目)我想做这样的事情: VB: Publ
在我看来,静态/强类型编程语言最宝贵的一点是它有助于重构:如果/当您更改任何 API,那么编译器会告诉您该更改破坏了什么。 我可以想象用运行时/弱类型语言编写代码......但我无法想象没有编译器的帮
正如我的名字所暗示的,我是一名 .NET 开发人员,但我对 Java 的兴趣越来越大,并且我有兴趣学习更多其他语言,因为这有助于我学习更多关于编程的知识。 无论如何,我的问题是:不带参数/不使用状态的
我在java中使用WireMock来 stub POST请求。该请求返回一个存储在我本地的 json 正文文件。 stub 看起来像这样: wireMockServer.stubFor(get(url
Python 是否有类构造函数的机制,即每当首次引用类时(而不是创建该对象的实例时)调用的函数?我知道其他一些语言中也存在这种情况,但我还没有在 Python 中遇到过。 基本上,我想初始化该函数中的
Python 是否有类构造函数的机制,即每当首次引用类时(而不是创建该对象的实例时)调用的函数?我知道其他一些语言中也存在这种情况,但我还没有在 Python 中遇到过。 基本上,我想初始化该函数中的
这个问题已经有答案了: What is the difference between dynamic and static polymorphism in Java? (14 个回答) 已关闭 4 年
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Static initializer in Java 我想知道这个静态的东西(抱歉,这是我第一次遇到这个)对一个类有
如果c++应用程序是按以下方式组织的 //file1.cpp static Y sgObj = X::getInitObject(0); //declared in file scope //fil
我有一个抽象类(AvergedDataRecord),我需要进一步抽象(DataRecord),这样我就可以将它扩展到原始类和一个新的具体类(SummedDataRecord),并且我在获取某些方法时
我正在尝试制作一个字符串枚举。这是我到目前为止所得到的, private class TypedEnum : IEnumerable { public IEnumerator GetEnume
我选修了一门名为“安全代码”的类(class),在下一个作业中,我们应该对一些 C 文件和 JavaEE Web 项目进行静态/动态分析。 我检查了“源监视器”并在 C 文件上运行它,但是(除非我不知
我有两个类,一个是登录类,一个是用户类。在 loggedIn 类中,我想显示我在用户登录时所做的共享首选项。 loginPrefs = getSharedPreferences("loginprefe
我在同一个 Activity 中有两个静态 fragment ,在“fragmentA”中我有一个自定义列表,当一个项目被点击时必须在“fragmentB”中出现一个细节,细节只在我改变屏幕方向时出现
在 Java 中是未修改方法变量,缺少final,每次都重新初始化限定符 静态方法 实例方法 如果 1. 或 2.(或两者)的答案是 final 限定符允许 Java 执行优化并存储方法变量只有一次?
我有两个类相互交互。第一个是中心的,如下: public class Datenbank { double winkelPanel = 0; double groessePanel = 0; doub
我有一个 mysql 数据库,它连接基于 Web 的 php 应用程序和 FoxPro 应用程序(是的,foxpro)。在之前的“开发人员”被解雇后开始处理这个问题。 无论如何,我熟悉 AES_Enc
我是一名优秀的程序员,十分优秀!