2013-08-18 1 views
5

Так что, если вы:Как проверить, указывает ли указатель void на NULL?

void *ptr = NULL; 

Что такое лучший способ проверить, если этот указатель является недействительным NULL?

Мой Обойти сейчас это:

if (*(void**)ptr == NULL) ... 

Но это не кажется, что лучший способ, так как я неявно предполагая PTR имеет тип пустоты ** (которой нет).

+0

Почему так сделать суету об этом –

+0

Читайте: [Могу ли я использовать 'если (указатель)' вместо 'если (указатель! = NULL) '?] (http://stackoverflow.com/questions/17772103/can-i-use-ifpointer-instead-of-ifpointer-null) –

+1

Обходное решение для * what *? – GManNickG

ответ

8

Я просто напишу if (!ptr).

NULL в основном только 0 и !0 это правда.

+2

Не на всех архитектурах вы будете писать не переносимый код. Возможно, это было 286 при использовании адресации сегмента, где NULL! = 0, но это было много десятилетий назад. – fadedbee

+1

Я бы сравнил ptr с NULL; как ptr == NULL. Нет гарантии, что NULL равен 0. – jacekmigacz

+0

Этот подход подходит в современном мире, в современных машинах? –

6

Обязательно укажите определение NULL.

#include <stddef.h> 

    void *X = NULL; 

    // do stuff 

    if (X != NULL) // etc. 

Если включить <stdio.h> и подобное, то stddef.h получает тянут в автоматическом режиме.

Наконец, интересно посмотреть на определение NULL в stddef.h, и, сделав это, вы увидите, почему ваше первоначальное предположение о том, что делать, интересно.

2

Указатель NULL - это указатель, который не указывает нигде. Его значение, как правило, определяется в stddef.h следующим образом:

#define NULL ((void*) 0) 

или

#define NULL 0 

Поскольку NULL равен нулю, if заявление, чтобы проверить, является ли NULL указатель проверки, является ли этот указатель равен нулю. Следовательно, if (ptr) оценивает 1, когда указатель не равен NULL, и, наоборот, if (!ptr) оценивает 1, когда указатель имеет значение NULL.

Ваш подход if (*(void**)ptr == NULL) направляет указатель void в качестве указателя на указатель, а затем пытается разыменовать его. Разделенный указатель на указатель дает указатель, поэтому он может показаться действительным подходом. Однако, поскольку ptr имеет значение NULL, когда вы его разыскиваете, вы вызываете неопределенное поведение.

Гораздо проще проверить if (ptr == NULL) или, используя краткую нотацию, if (!ptr).

+0

@EricPostpischil, вы правы, конечно, и я отредактировал соответственно. Спасибо за исправление. – verbose

1

Если ваш код удается скомпилировать при назначении void *ptr = NULL, то само собой разумеется, что простое if заявление для сравнения, если это NULL должно хватить, особенно потому, что NULL должны быть определены, если код может скомпилировать.

Пример достаточно способ проверить:

if(ptr==NULL) 
{ 
    rest of code... 
} 

Я написал небольшую тестовую программу, составленную с GCC на Linux, который работает:

int main() 
{ 
    void *ptr = NULL; 
    if(ptr==NULL) 
    { 
     return 1; 
    } 
    return 0; 
} 
+1

Это не удалось скомпилировать без '# include' для одного из нескольких стандартных заголовков, которые определяют' NULL'. –

0

Я знаю, что это немного старый пост, но хотел добавить что-то полезное.

То, что я обычно делаю что-то вроде этого,

Это моя функция.

void MyMethod( const void* l_pData ///< Source data 
       , size_t l_nLen  /**< Number of bytes to convert */) { 
    // Return if nothing is provided 
    if (l_pData == NULL || ((const char*)(l_pData))[0] == '\0' || 0 == l_nLen) { 
     return; 
    } 

    // Rest of the code 
} 

Вы можете проверить

- Null data 
- Empty data 
- Invalid length 

Вслед сверяются

MyMethod("", 10); 
MyMethod(" ", 10); 
MyMethod(NULL, 10); 
MyMethod("valid", 0); 
+1

Это вопрос C. C не имеет 'reinterpret_cast'. – user694733

+0

О, спасибо за указание :) Я буду адаптировать его для C. – SajithP