How to dynamically allocate adjacent 2D array in C ++?

I need a 2-digit character array for use in the garbage API, which absolutely requires the use of NOT arrays and vectors (a lot of attention to this, because all my searches just answered “use a vector”. I wish I could).

I figured out how to do this, it would be to allocate an external array of strings * character length instead of doing:

char** arr;
arr = new char*[100];
// for loop that allocates the internal arrays

But I'm not sure which method I need to use to make it contiguous? Do I need to first allocate an array to a 1D array, and then assign the 1D array to a two-dimensional array in pieces?

+4
source share
3 answers

: n * m , 2d.

... ...

, vector API , , vector - ( &vec[0] vec.data(), , ).

++, , n * m class, 2- , .

:

class array_2d
{
public:

   array_2d( std::size_t rows, std::size_t columns )
     : m_rows(rows), m_cols(columns), m_array( new char[rows * columns] )
   {
   }

   ~array_2d()
   {
       delete [] m_array;
   }

   // row-major vs column-major is up to your implementation
   T& operator()( std::ptrdiff_t row, std::ptrdiff_t col )
   {
      // optional: do bounds checking, throw std::out_of_range first

      return m_array[row * m_cols + col];
      // alternatively:
      // return m_array[col * m_rows + row];
   }

   // get pointer to the array (for raw calls)
   char* data()
   {
     return m_array;
   }

private:

   char* m_array; 
   std::size_t m_rows;
   std::size_t m_cols;
};

( char* std::unique_ptr<char[]> std::vector<char>, , , vector , )

(operator()) - , at(...); . :

auto array = array_2d(5,5); // create 5x5 array
auto& i01 = array(0,1); // access row 0, column 1

, [][] , 2d- ( (r,c)), - operator [] (untested):

class array_2d_proxy
{
public:
   array_2d_proxy( char* p ) : m_entry(p){}

   char& operator[]( std::ptrdiff_t col ){ return m_entry[col]; }

private:

   char* m_entry;
};

class array_2d
{
  ...
  array_2d_proxy operator[]( std::ptrdiff_t row )
  {
    return array_2d_proxy( m_array + (row * m_cols) );
  }
  ...
};

"" 2d-, :

auto& i00 = array[0][0];
+3

:

void array2d(int m, int n) {
    std::vector<char>  bytes(m * n);
    std::vector<char*> arrays;
    for (int i = 0; i != m * n; i += n) {
        arrays.push_back(bytes.data() + i);
    }
    char** array2d = arrays.data();
    // whatever
}
+2

The main problem in C ++ with “2d continuous arrays with variable column lengths” is that for access such as myArray[r][c], the compiler needs to know the size of the type column myArrayat compile time (unlike C, C ++ does not support arrays variable length (VLA)).

To overcome this, you can select a continuous block of characters and optionally create an array of pointers, where each pointer points to the beginning of a line. With this “representation”, you can indirectly touch a contiguous block of memory with myArray[r][c]-notation:

int main() {

    // variable nr of rows/columns:
    int rows = 2;
    int columns = 5;

    // allocate continuous block of memory
    char *contingousMemoryBlock = new char[rows*columns];

    // for demonstration purpose, fill in some content
    for (int i=0; i<rows*columns; i++) {
        contingousMemoryBlock[i] = '0' + i;
    }

    // make an array of pointers as a 2d-"view" of the memory block:
    char **arr2d= new char*[rows];
    for (int r=0; r<rows;r++) {
        arr2d[r] = contingousMemoryBlock + r*columns;
    }

    // access the continuous memory block as a 2d-array:
    for (int r=0; r<rows; r++) {
        for (int c=0; c<columns; c++) {
            cout << arr2d[r][c];
        }
        cout << endl;
    }
}
0
source

Source: https://habr.com/ru/post/1686164/


All Articles