Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在运行时或全局/静态变量的静态分析时重新初始化全局/静态内存 问题_C_Memory_Static_Initialization_Global - Fatal编程技术网

C 在运行时或全局/静态变量的静态分析时重新初始化全局/静态内存 问题

C 在运行时或全局/静态变量的静态分析时重新初始化全局/静态内存 问题,c,memory,static,initialization,global,C,Memory,Static,Initialization,Global,我正在从事一个大型C项目(C99),该项目大量使用全局变量(我知道,我知道)。该程序运行得相当好,但它最初设计为运行一次并退出 因此,它依赖于它的全局/静态内存以0(或它声明的任何值)初始化,并且在运行时它修改这些变量(就像大多数程序所做的那样) 但是,我想再次运行程序,而不是在完成时退出。我想制作一个对这个大型程序具有控制和可见性的父程序。完全了解正在运行的程序非常重要 该解决方案需要在macOS、Linux和Windows上运行 我考虑过: 1.分叉 制作一个用作“外壳”的小包装程序,并根据

我正在从事一个大型C项目(C99),该项目大量使用全局变量(我知道,我知道)。该程序运行得相当好,但它最初设计为运行一次并退出

因此,它依赖于它的全局/静态内存以0(或它声明的任何值)初始化,并且在运行时它修改这些变量(就像大多数程序所做的那样)

但是,我想再次运行程序,而不是在完成时退出。我想制作一个对这个大型程序具有控制和可见性的父程序。完全了解正在运行的程序非常重要

该解决方案需要在macOS、Linux和Windows上运行

我考虑过:

1.分叉 制作一个用作“外壳”的小包装程序,并根据需要执行大程序

赞成的意见
  • 操作系统需要将内存重置为正确的值
  • 保证按预期运行
欺骗
  • 失去了对程序的可见性
  • 在运行时无法从包装器检查正在执行的程序的内存,在启动前更难调整设置,更难收集运行时信息
  • 需要实现一个系统来获取程序的内部数据,这可能会涉及大量代码
  • 统一体验(共享GUI窗口等)
2.手动识别关键结构 仔细阅读源代码,多次运行程序,等待程序在正常检查或内存访问错误时崩溃

赞成的意见
  • 容易做
  • 容易启动
  • 高可视性、代码共享和统一
欺骗
  • 并不是每一个案例都能抓住,非常零碎
  • 费时
3.重构 将所有全局变量收集到单个结构中,以
memset
,为使用值初始化的变量创建初始值设定项。根据具体情况处理静态数据

赞成的意见
  • 概念上简单的大锤式方法
  • 高可视性、代码共享和统一
欺骗
  • 非常耗时,代码库很大,几乎涉及所有内容
4.魔杖 告诉操作系统重新初始化全局/静态内存。如果我需要保存一个值,我会将它存储在本地,然后在完成后重写它

赞成的意见
  • 基本完美:)
欺骗
  • 不存在(?)
  • 非常黑的魔法
  • 可能不会跨平台
  • 可能会激怒第三方LIB
我现在在做什么 我现在使用选项2,只是通过代码,依靠程序崩溃并为我指出正确的方向

我要说的是,这种方法让我达到了80%的目标。我已经识别并重新初始化了足够多的东西,程序或多或少可以重新运行。它不像我想象的那么广泛,它给了我很多希望

偶尔会发生奇怪的事情,或者它不能按预期运行,但它也不会崩溃。这使得追踪它变得更加困难


我只是需要一些东西让我得到最后的20%。可能是某种静态分析工具,或者是帮助我浏览源代码并查看全局变量的位置的工具。

要轻松检测全局变量和静态变量,您可以尝试执行像这样的cqlinq查询

from f in Fields where f.IsGlobal || f.IsStatic
select f

如果希望某个特定函数或特定文件中使用变量,也可以修改查询。

函数中的静态变量可能确实有问题-您甚至可能会认为它们应该设置为文件范围。使用方法2扩展为“对于定义任何全局变量的每个文件,添加一个将所有全局变量重置为默认值的
void filename\u reset(void)
函数”。如果这不是零,您将需要一个非默认数据的固定版本,可以在修改后的版本上进行复制。不要跳过任何全局变量-直到您知道您可以安全地这样做。然后安排生成对
filename1_reinit()的调用序列;filename2_reinit()等-每个文件一次呼叫。选项1是唯一的实际选项。选项2要求您拥有进入可执行文件的每一段代码的源代码。其中包括您可能拥有的第三方库。但是它也包括C运行时间和C标准库,我确信你没有。@ UsSer338 6109:标准C库不缓存很多,除非你计算区域设置(并且重新启动的代码可能需要考虑是否已经设置了区域设置,但可能能够说“否”)。C库之外的库是另一回事——很容易出现问题。POSIX库中非线程安全的函数可能会出现问题,例如,@JonathanLeffler
errno
。由
malloc
维护的信息。有关打开文件的信息。即使是
argv
指向的字符串,也允许程序更改。当程序退出时,所有内容都已清理,但如果您只是告诉程序重新开始,则不会清理。@user3386109:…内存已分配但未释放;环境变量集(但不是标准C的一部分)。有足够多的可能性表明,重新启动未设计为重新启动的软件(通过使用太多全局变量和通常不清理资源)是非常有问题的。