Так... давай-ка немного поправим твое понимание предмета.
В С/С++ существует такой тип даных, как указатель на данные. Его синтаксис выглядит так:
int* value;
Запись буквально означает что 'value' у нас будет хранить адрес на область данных с предположительной типизацией в четырехбайтовое знаковое целое. Внимательно! 'value' хранит только указатель, никаких данных о размере блока этих данных нет, никаких строгих оговорок о типе этих данных нет (только предположение что это 'int').
При формировании переменной оная, обычно, ничем никак не инициализируется. То есть, после определения нашего 'value' в его значении лежит любой немыслимый мусор. Внимательно! Нет никаких способов (кроме как обратиться и словить AV/SIGSEGV) определить что значение 'value' ссылается на правильный адрес. Поэтому этот самый мусор, который в 'value' и содержится, можно спокойно использовать как адрес блока данных и при обращении по этому адресу получить от ОСи по рукам.
Вопрос! Как этого избежать?
Есть очень простой и очень старый выход - определить некую магическую константу, которая точно смогла бы символизировать чистоту указателя (что указатель не одержит адреса). Именно такой константой 'NULL' и является.
Адрес на блок данных может быть абсолютно любым! Он может быть даже 0xA0L. Но если в значении указателя записан 0 (это и есть NULL), значит указатель чист - он не содержит в себе адрес на блок данных.
Итак! NULL - это не зло. NULL - это признак чистоты указателя!
Теперь перейдем к "тонкостям и нюансам нолика"...
Попробуй собрать такой код:
typedef int* p_int;
p_int value = p_int();
printf( "ptr : 0x%08x\n", value );
Вывод в консои будет : "ptr : 0x00000000". О чем это говорит? Это говорит о том, что возвращаемое инициализатором указателя значение (вот эта вот запись: "p_int()") всегда эквивалентно NULL.
Можно было бы с точно таким же холоднокровием написать вот так:
p_int value = NULL;
И все осталось бы по прежнему.
Дело в том, что NULL имеет тип "void*", а этот тип можно преобразовать абсолютно к любому иному указателю.
И NULL самостоятельно приводится к нужному типу в операторе присвоения указателя этого типа. Ноль - он и в Африке ноль.
Попробуй собрать такой код:
int* value = NULL;
delete value;
Если бы 'value' небыл инициализирован, то с превеликой вероятностью оператор delete привел бы к падению приложения. 'delete' воспринял бы мусор как правильный указатель и попробовал бы освободить память по этому указателю, а так как это мусор, ОСь эту попытку забрила бы, выдав программе красную карточку. Вместе с тем, оператор delete спроектирован так, чтобы не обращать внимания на NULL. Оператор просто тихо завершается если видит нулевой адрес.
Вывод: чистота NULL не нуждается в большей очистке! :)
Вот так. Надеюсь, моя простыня текста хоть немного да поможет тебе.
А по вопросу о функции - да возвращай NULL! Так все делают, чем ты хуже? ;)