Объявление вектора как глобальной переменной в С++

Хорошо ли объявлять вектор как глобальный в С++?

Это то, что я сделал.

#include <vector>
std::vector<int> vec;

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

Просьба сообщить.

Ответ 1

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

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

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

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

Все сказанное, хотя это безопасно, это не обязательно хорошая практика; он попадает в область любой другой глобальной переменной или доступной для всего мира бит памяти, которая может быть немного спорным предметом. Как правило, я бы посоветовал, как правило, избегать глобальной переменной, как правило. Хотя в некоторых случаях это может быть приемлемым, глобальный доступ противоречит вашей способности контролировать доступ к переменной и применять к ней инварианты и состояние, которое оно контролирует или подразумевает. Это может привести к сложным системам поддержки в качестве шкал кода, поскольку эти пути доступа четко не прописаны.

Ответ 2

В области глобальных переменных будет выделено только пространство для векторных метаданных. Содержимое вектора будет по-прежнему динамически распределено (конструкторы и деструкторы нормально работают для глобальных переменных).

Это та же ситуация для автоматической векторной переменной, например:

int main(void)
{
    std::vector<int> v;
    return 0;
}

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

Ответ 3

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

Это неправильное понимание.

Память не выделяется во время компиляции. Память выделяется при запуске программы, а затем во время программы, в зависимости от типов хранилищ переменных. И когда программа выключается, вся используемая им память возвращается в ОС, несмотря ни на что.

При достижении этого предела написанное может съесть в память, используемую другой переменной.

Нет. Объект std::vector<int> никогда не может использовать память, используемую другой переменной (-ами).

Теперь вернемся к вашему основному вопросу,

Хорошо ли объявлять вектор как глобальный в С++?

Нет. Избегайте глобальных переменных, независимо от их типов.

Ответ 4

Ну, vec - глобальная переменная, поэтому память для нее предположительно выделена из сегмента данных. Однако память для содержимого vec зависит от распределителя. По умолчанию, я думаю, что память для содержимого выделена из кучи.

Ответ 5

Глобальные переменные вообще являются плохой практикой. Они не будут "есть" в памяти другой переменной, как вы говорите, однако, это очень легко для вас, как программист что-то вникнуть. Например, все в программе имеет доступ к этому вектору, и поэтому все может получить доступ и изменить его. Вы можете или не хотите этого, но, скорее всего, вам этого не нужно.

Что касается распределения памяти, объекты, добавленные в вектор, все еще добавляются во время выполнения (потому что они не существуют во время компиляции!). Память также не выделяется во время компиляции. В вашей программе есть подпись, чтобы выделить эту память во время RUN. Подумайте об этом... если программа выделила память во время компиляции, вы бы не смогли запустить их на других машинах, не так ли? Память будет выделена на ВАШЕЙ машине, но не на других машинах. Следовательно, память должна быть выделена во время выполнения.

Ответ 6

Ваша программа не выделяет ничего во время компиляции - я думаю, вы имеете в виду время выполнения.

Вектор выделяет то, что он держит в куче (vec.size() * sizeof (/* то, что вы держите */)) - он держит sizeof (std::vector < > ) на том месте, где он был выделен. Глобальные переменные могут храниться в любом месте, это зависит от реализации.