Указатель, указывающий на пустой массив - PullRequest
9 голосов
/ 08 ноября 2010

У меня есть указатель, указывающий на начало массива, но мне нужно убедиться, что он нераспределен.Я думал о разыменовании указателя и проверке NULL, но это приводит к ошибке типа.Кто-нибудь может увидеть, что я делаю не так?

int mydispose(int *array){
    int i = 0;

    if(*array == NULL){
            return 1;
    }

    return ;

}

РЕДАКТИРОВАТЬ: Извините, если я неясно: у меня есть указатель, который указывает на начало массива, но я хотел быпроверить, является ли массив пустым.

Ответы [ 6 ]

11 голосов
/ 08 ноября 2010

*array == NULL неверно. Сначала вы разыменовываете указатель (который может привести к segfault, если указатель действительно равен нулю), а затем сравниваете его значение int со значением указателя. Более того, ваш компилятор прекрасно примет это ошибочное выражение, если NULL определено как просто 0, а не (void *) 0.

Вы должны проверить array == NULL, чтобы увидеть, относится ли переданный указатель к чему-либо, а затем разыменовать его только в случае, если это не NULL.

Однако имейте в виду, что разыменование ненулевого указателя также не является безопасной операцией. Если указатель содержит значение мусора, потому что он был размещен в стеке и не инициализирован, или если он ссылается на выделенную область памяти, могут возникнуть неприятные ошибки.

5 голосов
/ 08 ноября 2010

Вы хотите if (array == NULL) - но если вы сначала не инициализируете array в NULL, это тоже не принесет пользы.Я думаю, вам лучше сделать резервную копию и рассказать нам немного больше о том, чего вы пытаетесь достичь, и попытаться получить помощь, пытаясь достичь вашей общей цели.

1 голос
/ 08 ноября 2010

Непосредственная проблема с вашим кодом заключается в том, что вы разыменовываете array перед сравнением его с NULL.Тип выражения *array: int, а не int *.Не используйте оператор разыменования, и типы будут совпадать:

if (array == NULL) {...}

Обратите внимание, что неинициализированный указатель гарантированно содержит NULL, только если он был объявлен со статическим экстентом (т. Е. Он был объявлен либо в области видимости файла, либо сstatic ключевое слово перед ним).Точно так же вызов free для указателя не установит значение этого указателя в NULL;он будет содержать то же значение указателя, что и раньше, но теперь он будет недействительным.

1 голос
/ 08 ноября 2010

Вы не можете надежно проверить, выделена ли какая-либо область памяти. *array не является допустимым кодом, потому что он такой же, как array[0], но array[0] не выделен. Нераспределенная ячейка памяти может содержать любое значение.

Единственный вариант - убедиться, что вы получаете информацию о том, размещен ли массив вместе с вашим массивом. Популярная опция представляет нераспределенный массив как NULL, но вы можете выбрать и другую опцию.

Кстати, есть разница между пустым массивом (то есть массивом размера 0) и массивом, который вообще не выделяется. Первый вариант возникает, когда вы используете malloc(0), второй, когда ваш указатель вообще не инициализирован. Для malloc(0) разрешено возвращать NULL, но разрешено возвращать и ненулевой указатель (который вы, однако, не можете разыменовать). Оба способа действительны в соответствии со стандартом.

1 голос
/ 08 ноября 2010

Единственный безопасный способ определить статус распределения *array - это:

  1. Убедитесь, что для *array установлено значение NULL, он не выделен. int *array = NULL;
  2. Проверьте, равен ли массив NULL: if (array == NULL) return -1;
0 голосов
/ 08 ноября 2010

Вы должны использовать это так:

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