簡體   English   中英

矢量動態內存分配的私有成員向量

[英]Private member vector of vector dynamic memory allocation

我是C ++的新手(我學過Fortran編程),我想動態地為多維表分配內存。 該表是一個私有成員變量:

class theclass{
public:
  void setdim(void);
private:
  std::vector < std::vector <int> > thetable;
}

我想用函數setdim()設置thetable的維度。

void theclass::setdim(void){
  this->thetable.assign(1000,std::vector <int> (2000));
}

編譯這個程序沒問題,但是當我執行它時,我遇到了分段錯誤。

對我來說奇怪的是,這段代碼(見下)正是我想要的,除了它不使用我的類的私有成員變量:

std::vector < std::vector < int > > thetable;
thetable.assign(1000,std::vector <int> (2000));

順便說一句,如果thetable是一維向量,我也沒有問題。 在課堂里 :

std::vector < int > thetable;

如果在setdim中:

this->thetable.assign(1000,2);

所以我的問題是:為什么在2D矢量的表格與此表格之間存在“分配”這樣的差異? 我該怎么辦才能做我想做的事?

謝謝您的幫助,

最好的祝福,

- 傑弗羅伊

由於它與當地的,而不是你的類變量工作我的心靈調試力量告訴我你叫setdim上的一個空或無效的指針/實例theclass

謝謝大家的意見。 我正在去做一個只有有問題的部分的小源代碼的路上,當我試圖運行它時,它工作...我很困惑所以我試圖找到指令之間的差異。 最后,我發現我忘了一個

#include <vector>

在其中一個源文件中(主文件,但不是具有類定義的文件)。 這對我來說很奇怪,因為沒有它,我不明白它是如何編譯的......所以這應該是另一個問題,但我仍然不明白把這些放在哪里#include ... Fortran的生活更容易;-)

再次感謝你,

- 傑弗羅伊

一次安裝東西:

1)代碼更有用,因為大多數人都忽略了實際重要的一點。 因此,將您的代碼轉換為最簡單的可編譯示例,然后您可以在此處進行設置。

2)分段錯誤:

但是當我執行它時,我遇到了分段錯誤。

由於你沒有指針,這通常意味着你超越了數組的范圍。 C數組中的注意事項是從0 - >(n-1)訪問的,因此1000個元素的數組具有元素0 - > 999.如果訪問超出數組末尾,應用程序將不會抱怨但您將損壞內存。

檢查此轉換運算符[]到.at()。

thetable[0][5] = BLA

thetable.at(0).at(5) = BLA  // This tests the bounds and will 
                            // throw an exception if you make a mistake.

3)標識符綁定到具有最近范圍的變量。 因此,優良作法是為您的標識符指定唯一的名稱,以便它們不會發生沖突。 'thetable'指的是局部變量,而this-> thetable指的是成員。 它更容易給他們獨特的名字。

std::vector < std::vector < int > > thetable;
thetable.assign(1000,std::vector <int> (2000));

// This is not a good idea if you have a member called thetable.
// Some people (not me) like to prefix member variables with m_ to distinguish
// them from automatic local variables.

class theclass
{
     Type   m_thetable;

     void theMethod()
     {
         Type thetable;
         m_thetable = thetable;
     }

雖然很多人都喜歡你的方法,但如果你想要它快速(例如,使用矩陣,你需要一塊內存並自己編制索引)。

有許多的原因。 首先,你需要為頂級向量分配一個內存塊,為每行(或列,因為你來自FORTRAN土地......)分配一個向量。

因此,不是單個操作,而是n + 1。

這適用於每次處理此對象,復制,銷毀,你有什么。 您還存儲每行的向量(大小,容量)的開銷。 當然,如果每一行都是不同的大小,這是一個功能。

因此,考慮以下內容,硬編碼為了清晰度加倍:看看構造函數是多么簡單,以及像+ =這樣的操作有多簡單,因為它可以按順序遍歷整個塊,忽略索引。

通過兩個數組索引單個元素的速度也較慢。 計算機必須從對象訪問頂級向量,找到指針,跳轉到那里並找到第二個指針。

操作員()提供任意索引

class Matrix {
private:
  int m_rows, m_cols;
  double* m_data;
public:
  Matrix(int rows, int cols) : m_rows(rows), m_cols(cols), m_data(new double[rows*cols]
  {}

  ~Matrix() { delete [] m_data; }
  Matrix(const Matrix& orig) m_rows(orig.m_rows), m_cols(orig.m_cols),
              m_data(new double[m_rows * m_cols]
  {}
  // operator = too....


  Matrix& operator +=(const Matrix& right) {
    assert(m_rows == right.m_rows && m_cols == right.m_cols);
    for (int i = 0; i < m_rows*m_cols; i++)
      m_data[i] += right.m_data[i];
  }

  double& operator()(int r, int c) { return m_data[r * m_cols + c]; }
  double operator()(int r, int c) const { return m_data[r * m_cols + c]; }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM