Подтвердить что ты не робот

Статические глобальные переменные в С++

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

static int *pieces;

Тогда у меня есть функция, которая заполняет ее числами, которые я хочу там. Функция находится в пространстве имен, а пространство имен реализовано в собственном .cpp файле. Тем не менее, я импортирую файл заголовка в main.c и вызываю функцию из пространства имен, которое создает такой массив, как:

pieces = malloc(sizeof(int) * 128);

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

4b9b3361

Ответ 1

Static - это ключевое слово со многими значениями, и в этом конкретном случае это означает не глобальный (перефразирование)

Это означает, что каждый .cpp файл имеет свою собственную копию. Таким образом, при инициализации в main.cpp, он инициализируется ТОЛЬКО в main.cpp. Другие файлы все еще не инициализированы.

Прежде всего, чтобы исправить это, нужно удалить ключевое слово Static. Это приведет к возникновению проблемы "Несколько определений". Чтобы исправить это, вы должны определить переменную в файле .cpp и просто extern объявить ее в файле заголовка.


Изменить: вы просто выделяете ему память, не считается инициализацией. Вам необходимо инициализировать память до 0 после выделения.

Вы можете использовать new int[128]() вместо вашего более подробного синтаксиса malloc, и это будет выполнить инициализацию? Или вы можете взять легкий путь (для чего он нужен) и использовать std::vector

Ответ 2

Ключ таков:

static int *pieces;

Ты сказал, что положил это в свой заголовок. Это не способ экспорта символа. Любой файл, который включает заголовок, получит свою собственную статическую версию неинициализированного указателя под названием pieces.

Вместо этого вы помещаете это в свой заголовок:

extern int *pieces;

extern int init_pieces();

И в исходном файле вы выполните следующее:

static const size_t num_pieces = 128;

int *pieces = 0;

int init_pieces()
{
    pieces = malloc( num_pieces * sizeof(int) );
    return pieces != NULL;
}

Теперь, когда вы включаете свой заголовок, ваш исходный файл будет знать, чтобы получить pieces откуда-то еще, и будет ожидать, когда компоновщик будет работать там где. Я также предложил функцию init для массива. Однако я не добавил функцию "release".

Обратите внимание, что это все C, а не С++. Если вы используете С++, вы действительно должны использовать new или еще лучше, используйте vector.

Кроме того, при использовании статики в С++ помните об этом: статический порядок инициализации С++

Ответ 3

Для высокопроизводительного кода на разных архитектурах вам может понадобиться выделение malloc-y, а не родовое новое. Это связано с тем, что вы могли бы обернуть его чем-то вроде mymalloc(), а затем использовать функции, зависящие от архитектуры, такие как те, которые реализуют правильное выравнивание, чтобы избежать промахов в кеше и выполнять другие отличные вещи, предоставленные производителем оборудования, например IBM (Bluegene) или Intel (MIC). Все эти оптимизированные процедуры распределения имеют структуру типа malloc.