Нужна помощь в понимании этого кода с помощью malloc и указателей - PullRequest
0 голосов
/ 11 октября 2011

Вот небольшой фрагмент кода из статьи Википедии о malloc ():

    int *ptr;
    ptr = malloc(10 * sizeof (*ptr)); // Without a cast
    ptr = (int*)malloc(10 * sizeof (int)); // With a cast

Мне было интересно, может ли кто-нибудь помочь мне понять, что здесь происходит.Итак, из того, что я знаю , похоже, что это то, что происходит:

1) инициализировать целочисленный указатель, который указывает на NULL.Это указатель, поэтому его размер составляет 4 байта.Разыменование этого указателя вернет значение NULL.

2) Поскольку C допускает этот тип автоматического приведения, безопасно не включать приведение к int-указателю.У меня возникают проблемы с расшифровкой того, что именно подается в функцию malloc (хотя и почему).Кажется, что мы получаем размер разыменованного значения ptr.Но разве это не NULL?Таким образом, размер NULL равен 0, верно?И почему мы умножаем на 10 ??

3) Последняя строка - то же самое, что и выше, за исключением того, что приведение явно объявлено.(приведение от пустого указателя к указателю int).

Ответы [ 3 ]

4 голосов
/ 11 октября 2011

Я предполагаю, что мы говорим о Си здесь. Ответ другой для C ++.

1) полностью выключен. ptr - это указатель на int, вот и все. Он неинициализирован, поэтому не имеет детерминированного значения. Разыменование это неопределенное поведение - вы наверняка не получите 0! Указатель также, скорее всего, не будет указывать на 0. Размер ptr равен sizeof(ptr) или sizeof(int*); ничего больше. (В лучшем случае вы знаете, что это не больше, чем sizeof(void*).)

2/3) В C никогда не приводите результат malloc: int * p = malloc(sizeof(int) * 10);. Код выделяет достаточно памяти для 10 целых чисел, то есть в 10 раз больше, чем одно целое число; возвращаемое значение вызова является указателем на эту память.

1 голос
/ 11 октября 2011

Первая строка объявляет указатель на целое число, но не инициализирует его - поэтому он указывает на какой-то случайный фрагмент памяти, возможно, недействительный.Размер ptr - это любой размер указателя на int, вероятно, 4 или 8 байтов.Размер, на который он указывает, который вы получите, разыменовав его, когда он указывает где-то действительный, равен размеру, который имеет int.

Вторая строка выделяет достаточно памяти для 10 int скуча, затем присваивает ее ptr.Приведение не используется, но void *, возвращаемое malloc(), автоматически преобразуется в любой тип указателя, который требуется при назначении.sizeof (*ptr) дает размер разыменованного ptr, то есть размер того, на что указывает ptr (int).Для sizeof не имеет значения, действительно ли ptr указывает на допустимую память, просто то, каким будет тип.

Третья строка похожа на вторую, но с двумя изменениями: она явнопреобразует void * возврат из malloc() в int *, чтобы соответствовать типу ptr;и он использует sizeof с именем типа int, а не с выражением этого типа, например *ptr.Явное приведение не является обязательным, и некоторые люди категорически против его использования, но в итоге все сводится к предпочтениям.

После того, как любой из malloc() s ptr должен указывать на допустимое место в куче, его можно безопасно разыменовать, если malloc был успешным.

0 голосов
/ 05 марта 2016

Для строки 2 malloc () выделяет достаточно памяти для хранения 10 указателей.

malloc () - это функция общего назначения void поэтому он должен быть приведен к тому типу, который вы действительно хотите использовать, в приведенном выше примере указатель на int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...