C+中的指针+;;分段错误: 我刚刚开始学习C++,现在我正在使用指针。我不明白为什么会发生下面的事情

C+中的指针+;;分段错误: 我刚刚开始学习C++,现在我正在使用指针。我不明白为什么会发生下面的事情,c++,pointers,segmentation-fault,C++,Pointers,Segmentation Fault,假设我有两个类A和B。A有一个整型字段(int valueA),B有一个指针字段(指向A),A*A。下面我展示了这两个类 class A{ A::A(int value){ valueA = value; } void A::displayInfo (){ cout<<A<<endl; } } class B{ B::B(){ a=0; } void B::printInfo (){

假设我有两个类A和B。A有一个整型字段(int valueA),B有一个指针字段(指向A),A*A。下面我展示了这两个类

class A{
   A::A(int value){
    valueA = value;
}


 void A::displayInfo (){
      cout<<A<<endl;
    }
 }



class B{

    B::B(){
    a=0;
  }


  void B::printInfo (){
       a -> displayInfo(); //Segmentation fault
     }

  void B::process(){
     A new_A = A(5);
     a = &new_A;
     new_A.displayInfo(); //correct output
     a -> displayInfo();  //correct output
     }
  }
}



为了说明这一点,我有一个A.h和B.h文件,分别声明“int valueA;”和“A*A;”。我知道如果没有指针,这会容易得多,但我正在尝试学习指针在这里是如何工作的:D

a被分配给process()中的局部变量,因此在printInfo()中无效a被分配给process()中的局部变量,因此在printInfo()中无效变量
a
是方法的局部变量-在类级别声明它变量
a
是方法的局部变量-在类级别声明它

 A new_A = A(5);
 a = &new_A;
在这里,您可以创建
新的
,它是
进程的本地
并将其地址分配给
A
。当
过程
功能结束时,
new_A
超出范围并被销毁。现在
a
指向一个无效对象

这里真正的解决方案是不使用这样的指针,但如果您确实必须这样做,那么为了让某些东西持续到函数末尾之外,您需要动态地分配它。使用
a=新的a(5)执行此操作。您需要确保
删除一个
在程序中稍后的某个点,否则动态分配的内存将泄漏

在这里,您可以创建
新的
,它是
进程的本地
并将其地址分配给
A
。当
过程
功能结束时,
new_A
超出范围并被销毁。现在
a
指向一个无效对象



这里真正的解决方案是不使用这样的指针,但如果您确实必须这样做,那么为了让某些东西持续到函数末尾之外,您需要动态地分配它。使用
a=新的a(5)执行此操作。您需要确保
删除一个在程序中稍后的某个点,否则动态分配的内存将泄漏。

在类定义之后缺少分号,您不应该在类定义中使用
Class::Method
。我已经编辑了格式化代码,但没有触及错误。@Martinshaiters:没有。我在两个类中都没有看到任何成员变量声明,这个
B_对象()不创建对象。所以很明显你是在漏掉代码或者编造东西。请剪切并粘贴准确的代码和错误消息。@LightnessRacesinOrbit或我认为的那样。在类定义后缺少分号,您不应该在类定义中使用
Class::Method
。我已经编辑了格式化代码,但没有触及错误。@Martinshaiters:没有。我在两个类中都没有看到任何成员变量声明,这个
B_对象()不创建对象。所以很明显你是在漏掉代码或者编造东西。请剪切并粘贴准确的代码和准确的错误消息。@LightnessRacesinOrbit或我想的那样。我已经在我的B.h文件中声明了它,因此a不是本地的。您可能应该在代码片段中显示相关信息(变量声明)。变量范围可能是罪魁祸首。我已经在我的B.h文件中声明了它,因此a不是本地的。您可能应该在代码片段中显示相关信息(变量声明)。变量作用域可能是罪魁祸首。我想你应该把你的手指放在它上面——当它超出作用域时,a就会被破坏。我想我现在明白了,至少它为什么不工作了。是的,你是对的,做“a=新的a(5);”解决了问题。但是有没有一种方法可以创建一个新的a实例(比如new_a)并更新指针(a)以指向这个新实例呢?@FranXh这就是你之前所做的。问题是对象的生存期比指针的生存期短。指针继续指向对象以前所在的位置,即使在对象超出范围之后也是如此。确保对象的生命周期足够长的另一种方法是通过引用将其传递给
进程。然后你可以获取引用的地址,只要被引用的对象持续足够长的时间,你就会没事的。好的,我明白你的意思。然而,我尝试动态分配空间,现在它工作了。我可以做这样的事情吗?或者这是一种糟糕的设计技术?void B::process(){A new_A=A(5);A=new A;//动态分配空间(*A)=A;new_A.displayInfo();A->displayInfo();}@FranXh这有点傻,因为你不妨只做
A=new A(5)
而且根本不必为新的A而烦恼。我想你已经把手指放在它上面了-当它超出范围时,A就被破坏了。我想我现在明白了,至少它为什么不工作了。是的,你是对的,做“a=新的a(5);”解决了问题。但是有没有一种方法可以创建一个新的a实例(比如new_a)并更新指针(a)以指向这个新实例呢?@FranXh这就是你之前所做的。问题是对象的生存期比指针的生存期短。指针继续指向对象以前所在的位置,即使在对象超出范围之后也是如此。确保对象的生命周期足够长的另一种方法是通过引用将其传递给
进程。然后你可以获取引用的地址,只要被引用的对象持续足够长的时间,你就会没事的。好的,我明白你的意思。然而,我尝试动态分配空间,现在它工作了。我可以做这样的事情吗?或者这是一种糟糕的设计技术?void B::process(){A new_A=A(5);A=new A;//动态分配空间
 A new_A = A(5);
 a = &new_A;