混淆分割故障

Confusing segmentation fault

本文关键字:故障 分割      更新时间:2023-10-16

编辑:我基本上修改了整个问题,所以我可以提供一个可执行的例子…

我一直得到一个分割错误,我不能弄清楚。这是我的代码的压缩版本。我保持了原始的类层次结构,即使有些类没有相关的方法,因为我认为它与我的问题有关,特别是在我得到一些评论之后。

#import <vector>
using namespace std;
template<class Data = float>
  class Vector
  {
    // All pure virtual functions.
  };
template<class Data>
  class TranslationVector : public virtual Vector<Data>
  {
    // All pure virtual functions.
  };
template<class Data>
  class SimpleVector4 : public virtual Vector<Data>
  {
    public:
      SimpleVector4(const Data d0, const Data d1, const Data d2, const Data d3)
      {
        fData = new vector<Data> ;
        fData->push_back(d0);
        fData->push_back(d1);
        fData->push_back(d2);
        fData->push_back(d3);
      }
      vector<Data>*
      getData()
      {
        return (fData);
      }
    private:
      vector<Data>* fData;
  };
template<class Data>
  class SimpleTranslationVector4 : public SimpleVector4<Data> , public TranslationVector<Data>
  {
    public:
      SimpleTranslationVector4(const Data x, const Data y, const Data z, const Data w) :
        SimpleVector4<Data> (x, y, z, w)
      {
      }
  };
template<class Data = float>
  class Matrix
  {
    // All pure virtual functions.
  };
template<class Data>
  class TransformationMatrix : public virtual Matrix<Data>
  {
    // All pure virtual functions.
    virtual void
    translate(TranslationVector<Data>* const translation) = 0;
  };
template<class Data>
  class SimpleMatrix44 : public virtual Matrix<Data>
  {
    public:
      SimpleMatrix44()
      {
        fData = new vector<Data> (CELLS_IN_MATRIX, 0);
        setIdentity();
      }
      vector<Data>*
      getData()
      {
        return (fData);
      }
      void
      setIdentity()
      {
        fData->at(0) = 1;
        fData->at(1) = 0;
        fData->at(2) = 0;
        fData->at(3) = 0;
        fData->at(4) = 0;
        fData->at(5) = 1;
        fData->at(6) = 0;
        fData->at(7) = 0;
        fData->at(8) = 0;
        fData->at(9) = 0;
        fData->at(10) = 1;
        fData->at(11) = 0;
        fData->at(12) = 0;
        fData->at(13) = 0;
        fData->at(14) = 0;
        fData->at(15) = 1;
      }
    private:
      static const int CELLS_IN_MATRIX = 16;
      vector<Data>* fData;
  };
template<class Data>
  class SimpleTransformationMatrix44 : public SimpleMatrix44<Data> , public TransformationMatrix<Data>
  {
    public:
      SimpleTransformationMatrix44() :
        SimpleMatrix44<Data> ()
      {
      }
      void
      translate(TranslationVector<Data>* translation)
      {
        vector<Data> *data = SimpleMatrix44<Data>::getData();
        vector<Data> *transData = ((SimpleVector4<Data>*) translation)->getData();
        // The error occurs on this line:
        data->at(12) += data->at(0) * transData->at(0) + data->at(4) * transData->at(1) + data->at(8) * transData->at(2);
        data->at(13) += data->at(1) * transData->at(0) + data->at(5) * transData->at(1) + data->at(9) * transData->at(2);
        data->at(14) += data->at(2) * transData->at(0) + data->at(6) * transData->at(1) + data->at(10) * transData->at(2);
        data->at(15) += data->at(3) * transData->at(0) + data->at(7) * transData->at(1) + data->at(11) * transData->at(2);
      }
  };
int
main(int argc, char** argv)
{
  SimpleTransformationMatrix44<float> matrix1;
  matrix1.translate(new SimpleTranslationVector4<float> (0.0f, 10.0f, 0.0f, 1.0f));
  return 0;
}

我在发生错误的代码中进行了注释。从调试中可以看出,它实际上发生在vectorsize()函数中,而transData没有初始化。我怎么也弄不明白为什么transData没有初始化!什么好主意吗?

谢谢,

Gaz。

非继承类的强制类型转换似乎是您的错误。

让我们看看你的代码。在调用translate函数时,将SimpleTranslationVector4<float>*转换为TranslationVector<float>*。然后将转换后的值再次转换为SimpleVector4<float>*。但是SimpleVector4<float>不继承TranslationVector<float>

这段代码也会导致错误。

template<class Data>
class SimpleVector4 {
public:
    int a;
};
template<class Data>
class TranslationVector {
};
template<class Data>
class SimpleTranslationVector4 : public SimpleVector4<Data>,
public TranslationVector<Data> {
};
int main() {
    SimpleTranslationVector4<float> A;
    SimpleVector4<float>* b = (SimpleVector4<float>*)&A;
    TranslationVector<float>* c = (TranslationVector<float>*)&A;
    SimpleVector4<float>* d = (SimpleVector4<float>*)c;
    b->a = 1; // ok
    d->a = 1; // error
}

您正在不相关类型之间进行c风格的强制转换。这样不安全。您需要这样做的事实可能表明您的设计中存在问题,但请尝试替换此:

vector<Data>* transData = ((SimpleVector4<Data>*) translation)->SimpleVector4<Data>::getData();

与这个:

vector<Data>* transData = dynamic_cast<SimpleVector4<Data>*>(translation)->getData();