2017-01-18 9 views
3

Я не могу понять некоторые основные вещи в C++ и задавался вопросом. Пожалуйста, помогите мне. Я понимаю, что p указывает на память, которая будет 2D-матрицей размера 3x4.Выделение памяти для указателя многомерного массива с новым

int(*p)[3][4]; 

1) Почему я не могу выделить память, как показано ниже?

p = new int[3][4]; 

2) Должно быть как последовать за работой. Но почему?

p = new int [1][3][4]; //or new int [5][3][4]; etc 

3) Что означает следующая строка кода? Это семантически правильно, но что он делает? Что такое значение empty [] в следующей строке?

p = new int [ ][3][4]; 
+0

@Muscampester Нет, ничего не добавляю – eyllanesc

ответ

1

Поскольку в C термин «int * p» имеет две интерпретации. Вы можете рассматривать P как указатель на одно целое число, но его можно также считать указателем на массив целых чисел.

Общий пример, строки. char * a = "hello";

«a» - это указатель на один символ, «h», но чаще он рассматривается как указатель на массив символов, например, на строку.

Итак, вы можете сделать это: char * a = new char [6]; strcpy (a, "hello");

Я считаю, что ваш третий пример недействителен C++.

В то время как это: p = new int [9] [3] [4]; Выделяет массив из 9 двухмерных массивов 3x4.

Попробуйте этот тест:

int test() 
{ 
    int(* p)[3][4] = new int[1][3][4]; 

    printf("sizeof(p)=%d, sizeof(*p)=%d\n", sizeof(p), sizeof(*p)/sizeof(int)); 

    size_t q1 = (size_t)&p[0][0][0]; 
    size_t q2 = (size_t)&p[1][0][0]; 
    printf("p, diff: %d\n", (q2 - q1)/sizeof(int)); 

    size_t r1 = (size_t)&p[0][0][0]; 
    size_t r2 = (size_t)&p[0][1][0]; 
    printf("p, diff: %d\n", (r2 - r1)/sizeof(int)); 

    size_t s1 = (size_t)&p[0][0][0]; 
    size_t s2 = (size_t)&p[0][0][1]; 
    printf("p, diff: %d\n", (s2 - s1)/sizeof(int)); 
    return 0; 
} 
2

C++ является строго типизированным языком. int - это не то же самое, что и int*. Аналогично int[3] - это не тот же тип, что и int*. Но просто слегка сокрушите int[3] с палкой, и он развалится и упадет на int*. C++ делает это, потому что c делает это.


Почему я не могу выделить память, как следующий?

p = new int[3][4]; 

Поскольку new возвращает указатель на int[4]:

auto p1 = new int[3][4]; // int(*p1)[4] 

Массив имеет decayed указателю. Он имеет lost the type and first dimension. Было бы лучше избегать указателей на массивы и придерживаться using templates and references. Или еще лучше, предпочитают std::vector или std::array.

У вас может быть несколько указателей на тот же адрес, but with different types, который can be confusing.


2) Он должен быть как следующие работы. Но почему?

p = new int [1][3][4]; 

В этом примере массив int[3][4] с также распались на указатель:

auto p2 = new int [1][3][4]; // int(*p2)[3][4] 

Так вот значение, возвращаемое new может быть назначен p, потому что он имеет тот же тип. Обратите внимание, однако, что тип указателя не включает информацию о размере массива, он имеет только тип, который указывает на элементы, которые являются массивами более низкой размерности (которые не разлагаются на указатели).


3) Что следующая строка кода означает? Это семантически правильно , но что он делает? Что такое значение пустого [] в строке ?

p = new int [ ][3][4]; 

Это не всегда может составить, и если это произойдет, то это compiler extension, который будет определять значение пустых квадратных скобок.