C: Почему неназначенные указатели указывают на непредсказуемую память и НЕ указывают на NULL? - PullRequest
46 голосов
/ 23 июня 2010

Давным-давно я занимался программированием на Си для школы. Я помню кое-что, что я действительно ненавидел в C: неназначенные указатели не указывают на NULL.

Я спрашивал многих людей, включая учителей, почему в мире поведение по умолчанию для неназначенного указателя не указывает на NULL , так как для него непредсказуемо гораздо опаснее.

Ответ был предположительно исполнением, но я никогда не покупал это. Я думаю, что многие ошибки в истории программирования можно было бы избежать, если бы C по умолчанию был равен NULL.

Вот некоторый C-код, чтобы указать (каламбур), о чем я говорю:

#include <stdio.h>

void main() {

  int * randomA;
  int * randomB;
  int * nullA = NULL;
  int * nullB = NULL;


  printf("randomA: %p, randomB: %p, nullA: %p, nullB: %p\n\n", 
     randomA, randomB, nullA, nullB);
}

Который компилируется с предупреждениями (приятно видеть, что компиляторы C гораздо приятнее, чем когда я учился в школе) и выводит:

randomA: 0xb779eff4, randomB: 0x804844b, nullA: (ноль), nullB: (ноль)

Ответы [ 11 ]

0 голосов
/ 23 июня 2010

Я думаю, что это происходит из-за следующего: нет никаких причин, почему память должна содержать (при включении) определенные значения (0, NULL или что-то еще). Таким образом, если ранее не было специально написано, область памяти может содержать любое значение, которое, с вашей точки зрения, в любом случае является случайным (но это же местоположение могло быть использовано ранее другим программным обеспечением, и, таким образом, содержать значение, которое имело смысл для это приложение, например, счетчик, но с "вашей" точки зрения, это просто случайное число). Чтобы инициализировать его конкретным значением, вам потребуется как минимум еще одна инструкция; но есть ситуация, когда вам не нужна эта инициализация a priori , например v = malloc(x) назначит va действительный адрес или NULL, независимо от начального содержания v. Таким образом, его инициализация может считаться пустой тратой времени, и язык (например, C) может не делать этого a priori . Конечно, в настоящее время это в основном незначительно, и есть языки, в которых неинициализированные переменные имеют значения по умолчанию (null для указателей, когда поддерживается; 0 / 0.0 для числовых ... и т. Д. Ленивая инициализация, конечно, делает ее не столь дорогой для инициализации массив, скажем, 1 миллион элементов, поскольку они инициализируются для реального, только если доступ осуществляется до назначения).

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