Может ли статическое хранилище (в основном сегмент данных) вызвать ошибку сегментации? - PullRequest
2 голосов
/ 12 июля 2011

static хранилище определяется во время компиляции. Однако рассмотрим сценарий, в котором у нас много ленивой инициализации в функциях:

void foo ()
{
  static int a[1000];
}

Я не обсуждаю здесь практику кодирования, но технический аспект. Поскольку многие такие другие функции, как foo(), выполняются, эти многие static переменные будут введены в сегмент данных.

Будет ли компилятор выполнять ленивую инициализацию также в учетной записи при выделении места для сегмента данных . Если «Нет», вызовет ли это ошибку сегментации во время выполнения кода? (более вероятно, когда много static данных внутри template методов).

Ответы [ 4 ]

5 голосов
/ 12 июля 2011

Только потому, что инициализация ленива, распределение не. Стандарт требует, чтобы все статические переменные (включая локальные переменные) были инициализированы нулями до начала программы. Фактически, статический означает именно это (в данном случае): пространство для переменной присутствует на протяжении всего времени жизни программы.

3 голосов
/ 12 июля 2011

1) не будет "много" переменных для одной вещи. статическая переменная в области функций / методов очень похожа на глобальную переменную.

2) нет отложенного инициализации, который, скорее всего, инициализируется при запуске приложения вместе со всеми другими глобальными переменными.

3) я не вижу причин для ошибки

Подробнее о Статика (C ++)

EDIT: удалено заявление об обнулении

2 голосов
/ 12 июля 2011

Сколько таких foo () будет выполнено, эти статические переменные будут введены в сегмент данных.

Нет.Вы получаете только один foo()::a.В этом вся суть.

Будет ли компилятор выполнять ленивую инициализацию и в учетной записи, выделяя место для сегмента данных.Если «Нет», вызовет ли это ошибку сегментации во время выполнения кода?(более вероятно, когда много статических данных внутри методов шаблона).

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

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

0 голосов
/ 12 июля 2011

Краткий ответ: нет, не будет сегфо.

В приведенном ниже примере abc находится в сегменте данных , а def и x находятся в BSS.

#include <iostream>

int abc = 123;
int def;

int foo (int i) {
    static int x (i);
    return x;
}

int main () {
    std :: cout << foo (100) << " " << foo (200);
}

В этом примере выводится «100 100»: инициализация объектов области действия static происходит только во время первого вызова.

Хранилище для x такое же, как если бы это была глобальная переменная типа def.

Шаблоны в основном одинаковы, за исключением того, что foo был параметризован шаблонами, для каждого мгновения будет один x.

...