C语言 如何在函数内重置静态变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3488609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to reset static variables within a function
提问by Sue
Is there a way to reset variables declared as static within a function? The goal is to make sure that the function is not called with lingering values from an unrelated call. For example, I have a function opearting on columns of a matrix.
有没有办法重置函数中声明为静态的变量?目标是确保不会使用来自无关调用的延迟值调用该函数。例如,我有一个对矩阵列进行操作的函数。
int foo(matrix *A, int colnum, int rownum){
static int whichColumn;
static int *v; //vector of length A->nrows
if (column != whichColumn){
memset(v,0,size);
whichColumn = which;
}
//do other things
}
The function is called n times, once for each column. Is this a proper way of "re-setting" the static variable? Are there other general fool-proof ways of resetting static variables? For example, I want to make sure that if the call is made with a new matrix with possibly different dimensions then the vector v is resized and zeroed etc. It seems the easiest way may be to call the function with a NULL pointer:
该函数被调用 n 次,每列调用一次。这是“重新设置”静态变量的正确方法吗?是否有其他通用的万无一失的重置静态变量的方法?例如,我想确保如果调用是使用可能具有不同维度的新矩阵进行的,那么向量 v 会被调整大小和归零等。似乎最简单的方法可能是使用 NULL 指针调用函数:
int foo(matrix *A, int colnum, int rownum){
static int whichColumn;
static int *v; //vector of length A->nrows
if (A == NULL){
FREE(v);
whichColumn = 0;
}
//do other things
}
采纳答案by Jesse Collins
I'd recommend turning it into a struct and writing a small helper function for managing the semantics of what you're trying to do. It could return the buffer if the request is appropriate for its size, or create a new one on demand (and free the old one) if necessary.
我建议把它变成一个结构体并编写一个小的辅助函数来管理你想要做的事情的语义。如果请求适合其大小,它可以返回缓冲区,或者在必要时根据需要创建一个新缓冲区(并释放旧缓冲区)。
回答by Borealid
Use an idempotent initializer function and global variables instead.
改用幂等初始化函数和全局变量。
For example:
例如:
int foo;
int *m = NULL;
static void InitVars() {
foo = 0;
if (m != NULL) {
free(m);
}
m = malloc(sizeof(int)*5);
memset(m, 0, sizeof(int)*5);
}
If your initializer is really idempotent, you can call it again to reset the variables.
如果您的初始化程序真的是幂等的,您可以再次调用它来重置变量。
If you needthis to be called automagically, use __attribute__((constructor))(for GCC) like so:
如果您需要自动调用它,请使用__attribute__((constructor))(对于 GCC),如下所示:
static void InitVars __attribute__((constructor)) ();
However, you should note that if you need to do this, you should reconsider using in-function staticvariables and instead use passed-in fresh ones that are returned/written and passed to subsequent related calls.
但是,您应该注意,如果您需要这样做,您应该重新考虑使用函数内static变量,而是使用返回/写入并传递给后续相关调用的传入新变量。
回答by supercat
One approach I've seen used when a C module was imported to C++ was to surround the whole module with a class wrapper, and replace all static variables inside functions with uniquely-named "global" varaibles outside the functions. I don't know any good way to achieve a similar effect for projects involving multiple source files, though I'd like to know if one exists. I have some embedded system code in C, which I simulate by adding some C++ wrappers in VS2005. For example, I have I/O registers defined so that something like TX1CON = 0x5C; would translate into something like IOMAP(0x251).P = 0x5C; IOMAP is a property which would send "write 0x5C to address 0x251" to a hardware-simulation program. This approach works well, but I can't do a clean reset. Any ideas?
在将 C 模块导入 C++ 时,我见过的一种方法是用类包装器包围整个模块,并用函数外唯一命名的“全局”变量替换函数内的所有静态变量。对于涉及多个源文件的项目,我不知道有什么好的方法可以实现类似的效果,但我想知道是否存在。我在 C 中有一些嵌入式系统代码,我通过在 VS2005 中添加一些 C++ 包装器来模拟它们。例如,我定义了 I/O 寄存器,以便像 TX1CON = 0x5C; 将转化为类似 IOMAP(0x251).P = 0x5C; IOMAP 是一个属性,它将“写入 0x5C 到地址 0x251”发送到硬件模拟程序。这种方法效果很好,但我无法彻底重置。有任何想法吗?
回答by supercat
An approach which can sometimes be helpful if one needs a "reset" method which can hit an unknown number of functions or modules is to have a global counter for how many times that reset method has been called, and then have each function or module include code like:
如果一个人需要一个可以命中未知数量的函数或模块的“reset”方法,有时会很有帮助的一种方法是有一个全局计数器来记录调用了该 reset 方法的次数,然后让每个函数或模块包括代码如:
extern unsigned long global_reset_count;
void do_something(int whatever)
{
static ... this, that, the other, etc. ...;
static unsigned long my_reset_count;
if (my_reset_count != global_reset_count)
{
my_reset_count = global_reset_count;
... initialize this, that, the other, etc ...
}
}
In some multi-threading contexts, if the initialization of the static variables may depend upon some global variables, one may wish to replace the "if" with a "while"; in such a case; memory barriers may also be needed in such a case, though the exact requirements would vary depending upon the operating environment.
在一些多线程上下文中,如果静态变量的初始化可能依赖于一些全局变量,那么不妨将“if”替换为“while”;在这种情况下; 在这种情况下也可能需要内存屏障,尽管确切的要求会因操作环境而异。
Also, an alternative pattern that may be useful within embedded systems would be to have a modules_initializedglobal variable which gets set to 0 by the global reset method, and then have each module start with something like:
此外,在嵌入式系统中可能有用的另一种模式是拥有一个modules_initialized通过全局重置方法设置为 0的全局变量,然后让每个模块以如下内容开始:
if (!atomic_bit_test_and_set32(&modules_initialized, FOOBOZZ_MODULE_ID))
{
... Initialize module FOOBOZZ ...
}
This would require that there be no more than 32 module ID's, and would require that they be uniquely allocated somehow, but some systems can handle that pretty nicely. For example, a linker may allow one to define a "data section" from address 0-31 of an address space independent from any other; if each module declares a single-byte variable within that address space, the linker could generate the appropriate addresses for those variables.
这将要求模块 ID 不超过 32 个,并且需要以某种方式对它们进行唯一分配,但有些系统可以很好地处理这个问题。例如,链接器可能允许从地址空间的地址 0-31 定义一个“数据段”,与其他任何地址空间无关;如果每个模块在该地址空间内声明了一个单字节变量,则链接器可以为这些变量生成适当的地址。
回答by serup
you could build your function in such a way that if you call it with zero parameters, then it will reset its internal static variables
你可以这样构建你的函数,如果你用零参数调用它,那么它会重置它的内部静态变量
here is an example :
这是一个例子:
int foo(matrix *A = NULL, int colnum = 0, int rownum = 0)
{
static int whichColumn;
static int *v; //vector of length A->nrows
if (A == NULL){
FREE(v);
whichColumn = 0;
}
//do other things
}
You actually just have to call function to reset like this:
你实际上只需要像这样调用函数来重置:
foo(); // internal values would then be reset
Make sure that all your parameters to the function has default values, if for example you pass an optional, then make sure it has = boost::none as default value
确保函数的所有参数都具有默认值,例如,如果您传递一个可选值,则确保它具有 = boost::none 作为默认值

