Я в тупике, когда дело доходит до того, что фактический эффект таНоса является
malloc
вызова выделяет пространство для массива. Когда вы изначально объявлять ptr
, это не инициализируется точка к действительной ячейке памяти:
+---+
ptr: | | ----> ???
+---+
Попытка чтения или записей через ptr
в это время приведет к неопределенному поведению; ваш код может упасть напрямую, или он может как-то повредить хранилище, или может появиться для запуска без каких-либо проблем.
malloc
вызов выделяет пространство из кучи (иначе, динамический пул памяти) и присваивает адрес первого элемента этого пространства к ptr
:
+---+
ptr: | | ---+
+---+ |
... |
+------+
|
V
+---+
| | ptr[0]
+---+
| | ptr[1]
+---+
...
Обратите внимание, что (int *)
бросок на malloc
звонок не был необходим со времен стандарта 1989 года и фактически считается плохой практикой (под C89 он может маскировать ошибку). ИМО, лучший способ, чтобы написать malloc
вызова является
T *p = malloc(N * sizeof *p);
где T
любого типа, и N
этого количества элементов типа T
вы хотите выделить. Поскольку выражение *p
имеет тип T
, sizeof *p
равнозначно sizeof (T)
.
и что все на самом деле (ptr + i).
*(ptr + i)
эквивалентно ptr[i]
, так
*ptr = 'x';
*(ptr + 1) = 'x';
эквивалентны написанию
ptr[0] = 'x';
ptr[1] = 'x';
Пожалуйста, обратите внимание, что
*(ptr +99) = 'x';
находится вне диапазона массива вас» выделено; вы выделяете достаточно места для 25 целых чисел.Опять же, эта операция (и любая операция *(ptr + i) = 'x';
, где i
больше 24) приведет к неопределенному поведению, и ваш код может привести к сбою, повреждению данных или иным образом.
Арифметика указателя учитывает направленный тип; ptr + 1
дает адрес следующего целочисленного объекта, следующего за номером ptr
. Таким образом, если ptr
составляет 0x8000
и sizeof (int)
равно 4, то ptr + 1
дает 0x8004
, не0x8001
.
[Пожалуйста, просмотрите эту дискуссию о том, почему бы не использовать возвращаемое значение 'malloc()' и family в 'C'.] (Http://stackoverflow.com/q/605845/2173917). –
malloc не обязательно выделяет 100 байтов, он выделяет '25 * sizeof (int)' и '* (ptr + n)', потому что выделенная память смежна, поэтому '* (ptr + 0)' даст вам int на первое местоположение '* (ptr + 1)' второе и так далее. Это очень похоже на доступ к массивам C, и вы можете использовать тот же синтаксис. I.E '* (ptr + 0)' совпадает с 'ptr [0]' – George
hint: '* (ptr + 1)' такой же, как 'ptr [1]'. – dbush