Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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+中使用非法指针+;?_C++ - Fatal编程技术网

C++ 有什么方法可以避免在C+中使用非法指针+;?

C++ 有什么方法可以避免在C+中使用非法指针+;?,c++,C++,我有一个复杂的a类: class A{ ... }; 类B是include A的指针,它有一个返回指针的方法 class B{ A* GetA(){return pA;} A* pA; }; 然后,当我使用“GetA”获取a的指针时,使用非法指针更容易,如: void func(A* p){ B b; p = b.GetA(); } 当我使用“func”时,我只得到一个非法指针。 上面的代码只是一个示例。我发现在多线程环境中很容易犯这个错误 有没有办法让我确保避免这些错误 P.> C++

我有一个复杂的a类:

class A{
...
};
类B是include A的指针,它有一个返回指针的方法

class B{
A* GetA(){return pA;}
A* pA;
};
然后,当我使用“GetA”获取a的指针时,使用非法指针更容易,如:

void func(A* p){
B b;
p = b.GetA();
}
当我使用“func”时,我只得到一个非法指针。 上面的代码只是一个示例。我发现在多线程环境中很容易犯这个错误

有没有办法让我确保避免这些错误


<> P.> C++中没有一般方法来保护自己不受非法指针访问,但是有一些习惯用法可以帮助保护自己。

将类保持为表示概念/对象,不要公开对它们可能包含的任何指针的直接访问。例如,更喜欢描述性方法,或类似容器的类
begin
/
end
样式方法

管理指针时,首选首先使用标准容器,如
vector
。它们经过高度调优和调试,可以避免许多问题,因为它们已经拥有了所有正确的构造函数、赋值、析构函数等

如果无法使用标准容器,请根据您的指针需要,选择智能指针,如
唯一\u ptr
范围\u ptr
共享\u ptr
弱\u ptr
。通过使用适当的智能指针,您几乎不可能无意中犯编码错误

即使使用所有这些指导原则,您也始终可以绕过您尝试实施的任何保护。如果您发现自己使用了很多类型转换,您应该后退一步,重新检查您的设计


在您的情况下,我不仅会使
pA
无法通过访问器访问,而且也不会使其成为原始指针。

如果您将构造函数中的指针初始化为NULL:

class B {
    B() {
        pA = NULL;
    }
    A* GetA(){return pA;}
    A* pA;
}
然后可以在使用指针之前检查指针是否为非空

void func(A* p){
    B b;
    p = b.GetA();
    if(p != NULL) {
        //use p
    }
}
另外,您传入一个指向函数的指针,然后在不使用它的情况下分配给它,这似乎很奇怪<代码>p=b.GetA()不会更改
func
之外的任何内容。也许你想做这样的事

//Caller passes reference to their pointer, caller's pointer gets set.
void func(A *&p) {
    B b;
    p = b.GetA();
}
//Caller passes pointer to their pointer, caller's pointer gets set.
void func(A **p){
    B b;
    if(p != NULL) {
        *p = b.GetA();
    }
}

考虑SoeDypPTR而不是原始指针?这是一个编码错误,触发未定义的行为;它与多线程无关。你的编译器不会警告你这样的情况吗?考虑在<代码> B/<代码>构造函数中初始化<代码> Pa/代码>。如果没有有效的
pA
,则无法创建
B
的实例。可能会重复使用ctor初始化它。它将使它在对象的生命周期内有效。我认为它只在方法“func”中有用,当func返回时,“b”将被破坏,然后返回值p将是非法指针,它将不等于“NULL”(0xcccc meybe),将其与“NULL”进行比较是无用的,这取决于
pA
的有效值是如何分配的。如果动态分配内存,指针在
b
超出范围后仍然有效。但是为什么指针的值会改变呢?这个值不会改变,除非给它分配了一个新的值。让我们认为b是一个容器,pA是b中的元素。当我选择pA时,这意味着我有一个复制指针pA'指向存储在b中的pA,然后pA'与b没有关系。当b被取消定向时,b中的pA将是自由的。但是,因为pA'是pA的副本,所以pA'仍然指向由pA释放的内存。所以,当我再次使用pA'时,它将是一个错误。啊。如果在B的析构函数中释放pA,则是,pA的副本将指向无效的内存位置。然而,你需要在B的析构函数中显式释放pA。pA是指向一个数据块的指针,我应该将它共享给几个线程。我无法在b区外释放它。它应该在b内进行管理。所以我想找到一种方法,当我在B中释放pA时,它可以防止我在B之外使用这些非法指针。