Давайте сначала очистим эти вызовы. C не требует, чтобы вы произвели результат malloc
, и это считается плохой практикой (C++, с другой стороны, делает, требующий приведения, но вы не должны использовать malloc
в C++). Кроме того, вы можете передать разыменованный цель в качестве операнда к sizeof
, поэтому основной формой любого malloc
вызова выглядит
T *p = malloc(sizeof *p * N);
Это выделяет достаточное пространство для N
объектов типа T
и назначает результирующий указатель на p
. Доступ к каждому элементу можно получить с помощью p[i]
.
Таким образом, в первом случае, вы делаете
struct complex *ptr1 = malloc(sizeof *ptr1 * 4);
Это резервирует пространство для 4-х объектов типа struct complex
, каждая из которых доступна как ptr1[i]
. Это более простой случай.
struct complex (*ptr1)[4] = malloc(sizeof *ptr1);
Это выделяет пространство для 1 объекта типа struct complex [4]
(IOW, 4-элемент массива struct complex
а) и назначает результирующий указатель на ptr1
. Доступ к каждому элементу будет либо (*ptr1)[i]
, либоptr1[0][i]
. Вы бы действительно только использовать эту форму, если вы пытаетесь выделить пространство для 2-мерного массива struct complex
:
struct complex (*p)[4] = malloc(sizeof *p * N);
Это выделяет пространство для N
4-элементных массивов, или более просто массив N
x4, из struct complex
. Каждому элементу будет доступ как p[i][j]
.
Добро пожаловать в переполнение стека! [Пожалуйста, ознакомьтесь с этим обсуждением, почему бы не использовать возвращаемое значение 'malloc()' и family в 'C'.] (Http://stackoverflow.com/q/605845/2173917). –
Номер 2 является указателем на массив. Это запутанно, сложно использовать и очень редко полезно. Вы почти всегда хотите номер 1. –
В последнем вы резервируете слишком мало места: для 1 struct complex, а не массива из 4 структурных комплексов + все, что было сказано ранее. –