C: статический массив - PullRequest
       14

C: статический массив

5 голосов
/ 16 февраля 2009

Мне нужно иметь static void* array[1024]; в библиотеке, и мне нужно, чтобы он был установлен в NULL для каждой записи.

Мой вопрос о том, как наилучшим образом установить для всего массива значение NULL, является ли memset (array, NULL, sizeof (void*) * 1024) лучшим решением?

Ответы [ 5 ]

25 голосов
/ 16 февраля 2009

static указатели автоматически инициализируются как NULL. См. C99: TC3 6.7.8, §10:

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

  • если он имеет тип указателя, он инициализируется нулевым указателем;
  • если он имеет арифметический тип, он инициализируется нулем (положительным или без знака);
  • если это агрегат, каждый элемент инициализируется (рекурсивно) в соответствии с этими правилами;
  • если это объединение, первый именованный элемент инициализируется (рекурсивно) в соответствии с этими правилами.

Кроме того, вопреки тому, что написали другие,

memset(array, 0, sizeof(array));

не гарантирует нулевые указатели. В некоторых системах указатель со всеми битами, установленными на 0, может быть действительным. Для основных систем это не так, но со встроенными системами никто не знает.

Безопасный способ установить все записи в нулевой указатель - это либо зациклить сами записи и установить их на NULL, либо использовать неинициализированный массив static, который вы можете memcpy() над нужным массивом. установить на NULL.

9 голосов
/ 16 февраля 2009
static void* array[1024] = {0};

или, как указывает kmkaplan в комментарии, просто:

static void* array[1024];

хотя я предпочитаю первое решение, просто чтобы напомнить, что оно установлено на нули (компилятор не должен генерировать для этого никакого кода, если только он не мертв)

Вам вообще не нужно его устанавливать, поскольку переменные уровня файла все равно инициализируются нулями.

Если вам нужно сбросить их в NULL в какой-то момент после запуска, используйте:

memset(array, 0, sizeof(array));

Это работает на большинстве платформ (на каждой, которую я когда-либо видел, и это довольно много), поскольку нулевой указатель обычно равен нулю битов. Но стандарт не гарантирует этого, поэтому на этих непонятных платформах безопаснее:

for (i = 0; i < sizeof(array) / sizeof(void*); i++)
    array[i] = NULL;
3 голосов
/ 16 февраля 2009

memset сделает это во время выполнения.

static void* array[1024] = {0};

, предложенный Pax, сделает это во время компиляции и увеличит размер исполняемого файла.

Для библиотеки я считаю memset более подходящей.

1 голос
/ 16 февраля 2009

Все, что вам нужно, это:


static void* array[1024];

поскольку статические переменные в любом случае инициализируются равными 0, поэтому вам не нужно запускать этот массив, это произойдет автоматически.

0 голосов
/ 16 февраля 2009

Нет, это неправильно. Вы не учитываете размер каждого элемента.

memset(array, 0, sizeof(array)); // this works only on static arrays.

Как правило, вы должны использовать:

memset(array_reference, 0, size_of_array * sizeof(array_element_type));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...