2

Мне нужно создать структуру, которая содержит переменное число «char [2]», т. Е. Статические массивы из 2 символов.C++ динамически распределенный массив статически размерных массивов

Мой вопрос: как мне выделить память для x числа char [2].

Я попытался это (предполагая, что Int х определен):

char** m = NULL; 
m = new char[x][2]; 
... 
delete [] m; 

(он не работал)

Я понимаю, что я мог бы использовать зЬй :: вектор < полукокса [2] > как контейнер, но мне любопытно, как это будет сделано с необработанными указателями.

Я очень новичок в C++ и стараюсь учиться.

ответ

4

В своем коде, тип «м» не совпадает с «новым» вызова. Чего вы хотите:

char (*m)[2] = NULL; 
m = new char[x][2]; 
... 
delete [] m; 

м представляет собой указатель на массивы 2 символов, и вы вызываете новый, чтобы получить массив х массивов 2 символов и точки т на первой.

+1

@j_random_hacker, Это «указатель на массив 2 символов». Никакого массива из них. «массив указателя на массив из двух символов» выглядит как «char (* m [N]) [2];' и может использоваться, если вы сделали N независимых таких «новых» вызовов :) +1 @Chris xD –

+0

You «Совершенно верно - как я это испортил ?! Я удалил этот вводящий в заблуждение комментарий. –

+1

+1. Хотя часто бывает проще использовать typedef: 'typedef char char2 [2]; char2 * m = new char [x] [2]; ' –

0
unsigned x=10; 
typedef char A2[2]; 
A2 *m=new A2[x]; 
m[0][1]='a'; 
m[9][0]='b'; 
delete[] m; 

C Многомерные массивы (где все, кроме первых измерений, постоянные), расположены смежно.

Если вы хотите (потенциально зазубренный) многомерный массив, который представляет собой 1d массив 1d массивов, то есть в цикле:

char **m=new char *[x]; 
    for (unsigned i=0;i<x;++i) m[i]=new char[2]; 
    ... 
    for (unsigned i=0;i<x;++i) delete[] m[i]; 
    delete[] m; 
4

Я считаю, что следующий код более читабельным, чем char[n][2]:

typedef char wchar[2]; // array of two chars 
const size_t n = 100; // some const 
wchar* x = new wchar[n]; // array of wchars, where wchar is array of two chars 

// here is still a problem that you could write the following 
x[5][5] = 0;    // not what you expected? 

delete[] x;    // clean up 

Если известно о внутренней структуре WCHAR, код будет более понятным, если мы объявим его следующим образом:

// using struct is just gives names to chars in wchar, without performance drop 
struct wchar { 
    char h; 
    char l; 
}; 

... 

const size_t n = 100; // some const 
wchar* x = new wchar[n]; // array of wchars 

x[0].h = 0; 
x[0].l = 0; 

delete[] x;    // clean up 

И, наконец, потому что мы используем C++, нет необходимости использовать C массивы:

const size_t n = 100; // some const 
typedef std::tr1::array<wchar, n> my_arr; 
my_arr* x = new my_arr; 

(*x)[0].h = 0; 
(*x)[0].l = 0; 

delete x; 

Еще один довольно безопасный вариант с проверкой диапазона времени компиляции:

template<int n_max> 
struct array_n { 
    char v[2*n_max]; 

    template<size_t n, size_t s> 
    char& get() { 
     BOOST_STATIC_ASSERT(s < 2); 
     BOOST_STATIC_ASSERT(n < n_max); 
     return v[n*2+s]; 
    }; 
}; 

int main(int argc, char**argv) 
{ 
    const size_t n = 100; // some const 
    typedef array_n<100> my_arr; 
    my_arr* x = new my_arr; 

    x->get<10, 1>() = 0; // ok 
    x->get<50, 0>() = 0; // ok 
    x->get<10, 2>() = 0; // compile time error 
    x->get<500, 0>() = 0; // compile time error 

    delete x; 
} 
+0

Nice. Одна вещь, которую нужно знать с помощью метода typedef, заключается в том, что если вам придётся выделить один 'wchar' (* not * массив' wchar' - например 'wchar * m = new wchar;'), вы должны * still * удалить его с помощью 'delete [] m;'. лампочка заметила это уродливое отверстие в другом потоке. –

+0

Спасибо за ваш ответ. Это все более простые способы сделать это. – ejm

+0

@j_random_hacker, поэтому использовать 'struct' предпочтительнее. –