Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.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_Pointers_Compiler Warnings - Fatal编程技术网

C 防止本地指针

C 防止本地指针,c,pointers,compiler-warnings,C,Pointers,Compiler Warnings,也许这是一个新手问题,但是在C/C++中是否有一种方法可以防止函数接受指向局部变量的指针 考虑以下代码: int* fun(void) { int a; return &a; } 编译器将生成无法返回指针的警告。现在考虑这个问题: int* g; void save(int* a) { g = a; } void bad(void) { int a; save(&a); } 这将在没有警告的情况下通过编译器,这是错误的。是否有某种属性或东西可以防止这种情况发生?

也许这是一个新手问题,但是在C/C++中是否有一种方法可以防止函数接受指向局部变量的指针

考虑以下代码:

int* fun(void)
{
 int a;
 return &a;
}
编译器将生成无法返回指针的警告。现在考虑这个问题:

int* g;

void save(int* a)
{
 g = a;
}

void bad(void)
{
 int a;
 save(&a);
}
这将在没有警告的情况下通过编译器,这是错误的。是否有某种属性或东西可以防止这种情况发生?例如:

void save(int __this_pointer_must_not_be_local__ * a)
{
 g = a;
}

如果有人知道答案,请提前感谢。

不,没有可靠且可移植的方法来区分指向本地的指针和指向堆对象的指针。也没有办法以声明的方式防止这种情况


有些黑客依赖于特定系统的内存布局,它们在运行时通过调用未指定的行为(请参见示例)工作,但如果您决定尝试,则只能靠您自己。

使用调试堆进行调试生成至少有一种方法(默认):

有一个分配头,以gap结尾,因此指针前面有0xFDFD的可能性不大-不完美,但可能有帮助

if (\*((int\*)pointer-1) == 0xFDFDFD) { // stack pointer }

代码审查。。。代码分析器,如lint?代码审查、静态分析。你所要求的实际上是非常非常复杂的。如果我想做
void f(){int b;save(&b);/*dostuff*/save(NULL);}
?重要的不一定是变量是“局部的”;这也不好<代码>int*p=newint();save(p);删除p@CharlesBailey:有很多不好的东西;OP询问的是一个编译器似乎已经能够识别的特定对象(用于警告返回本地指针的逻辑)。@ScottHunter:我的观点是,存储指向本地对象的指针并不一定是坏的。将其标记为错误将产生误报。但是如果编译器cam识别函数何时尝试返回本地指针,并且如果存在OP建议的属性,为什么编译器不能使用相同的逻辑生成警告?@ScottHunter,因为编译器无法通过静态分析代码来可靠地确定警告。将指针存储在全局变量中是避免检查的唯一方法—可以将其存储在结构成员中,转换为字节数组,等等。添加一个如此不可靠的检查将无法达到目的。这与已实施的返回检查有何不同?@Scott。因为编译器知道返回的指针在“return”之后将不再有效。在其他情况下,它无法可靠地确定指针是否将在函数结束后使用。结果要么是无用的误报警告(人们很快就会开始忽略),要么是漏报案例(这将破坏目的)。为了避免射中脚部,瞄准正确比让枪朝下时不起作用要好得多。
if (\*((int\*)pointer-1) == 0xFDFDFD) { // stack pointer }