【问题标题】:Pointer assignment and segmentation fault指针分配和分段错误
【发布时间】:2012-07-22 16:24:55
【问题描述】:

我对 C++ 还很陌生,并且使用类似于以下代码的指针分配不断出现分段错误,我知道这意味着我正在访问尚未分配的内存,但我看不到在哪里:

我有两个班级:

class ClassA{ //class a decl.
  ClassB** oArray;
  unsigned int x;
 public:
  ClassA(unsigned int X);
  void oMember(ClassB* classb);
}


ClassA::ClassA(unsigned int X){ //Constructor for class a
  x = X;
  oArray = new ClassB* [x];

 for (unsigned int i = 0; i < x; i++){
        oArray = NULL; 
    }
}

class ClassB{ //rough decl of class B
  public:
   getId();
}

我有一个类成员函数,它接收指向另一个类的指针,如下所示:

void ClassA::oMember(ClassB* classb){
   unsigned int cID = classb.getId(); //defined in class b
   oArray[cID] = classb; //if cID is less than x defined in constructor, is this legal?
}

我只想将数组的第 cIDth 成员指向 classb。

我不断收到与上述类似的分配错误。我不太清楚为什么,我打印了 cID,它肯定小于我们在 ClassA 的构造函数中声明的数组的大小。

为什么这个分配是非法的,或者为什么我得到一个分段错误?

【问题讨论】:

  • 由于您的班级正在分配内存,您应该遵循以下内容:Rule of Three。另一方面,ClassB *classb) { ... classb.getId(); 不应该编译。
  • 如果您发布有助于我们重现问题的代码(听到的代码无法编译),您会更容易做到这一点。否则代码有很多问题,我们不太可能真正帮助您。
  • @pmr,好的,我会发布代码
  • @MyName:你不应该使用指针。我不确定课堂上双指针的意图是什么。在构造函数第 9 行中,您分配 RegisteredVMs 指针。在紧接的下一个循环中,您多次删除该指针。为什么不简单地使用向量或映射并完全避免使用指针?

标签: c++ class pointers g++


【解决方案1】:

正如我们在chat中意识到的那样,我只是将问题记录在这里以供参考。

问题出在片子上

RegisteredVMs = new VendingMachine *[nVendingMachines];
for (unsigned int i = 0; i < nVendingMachines; i++){
   RegisteredVMs = NULL; 
}

RegisteredVMs 被分配并立即设置为 NULL。 稍后在导致 seg 的 VMregister() 函数中访问该指针。故障。

指针很难而且很容易出错。只有在没有其他方法的情况下才使用它们。由于这是一个家庭作业问题,并且您说您在界面上没有发言权,我看到您必须使用它们。

【讨论】:

    【解决方案2】:

    我认为您应该将您的 ClassA 更改为

    class ClassA{
      std::map<int, std::shared_ptr<ClassB> > mMap;
    
     public:
      ClassA();
    };
    

    现在 A 类不需要知道数组大小,mMap 将确保您没有非常稀疏的数组。

    【讨论】:

      【解决方案3】:

      我认为 classb.getId() 应该是 classb-&gt;getId() 而不是只要 classb 是一个指针。嗯,这应该是编译器错误,我认为这不是你得到分段错误的原因。

      你确定你用那个特定的构造函数实例化了ClassA 吗?如果没有,xoArray 可能不会被初始化。

      我没有你的代码。但是,当我修改了要遵循的代码段时,我没有发现分段错误或编译器警告。

      class ClassB {
      public:
          int getId();
      };
      
      class ClassA {
          ClassB** oArray;
          unsigned int x;
      public:
          ClassA(unsigned int X);
          void oMember(ClassB* classb);
      };
      
      int ClassB::getId() {
          return 0;
      }
      
      ClassA::ClassA(unsigned int X) {
          x = X;
          oArray = new ClassB* [x];
      }
      
      void ClassA::oMember(ClassB* classb) {
          unsigned int cID = classb->getId();
          oArray[cID] = classb;
      }
      
      int main(int argc, char** argv) {
          ClassA a(12);
          ClassB b;
          a.oMember(&b);
          return 0;
      }
      

      【讨论】:

      • 糟糕。问题描述发生了显着变化。我将保留此答案。
      • 非常感谢。是的,我有一个更简单的版本,但需要实际代码,所以我更改了它。你所概述的对我有帮助。我会看看我的 main 函数,看看我是否正确调用了这些函数。
      • 您的代码确实有效.. 可能是另一个导致问题的类。我仍然遇到段错误。
      猜你喜欢
      • 2016-01-02
      • 1970-01-01
      • 2020-02-18
      • 1970-01-01
      • 2011-07-23
      • 2013-10-03
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多