Одинаковое назначение памяти для двух статических переменных - PullRequest
0 голосов
/ 04 января 2019

У меня есть код ниже, и я вижу, что две переменные были назначены с тем же адресом.Обе переменные совершенно разного типа.Есть ли в любом случае я могу аннулировать это?И при каких обстоятельствах одна и та же память выделяется обеим переменным.

static int Sw_Type [];
static BOOL Sw_Update;

void main()
{
  int i;
  int bytes = 3;
  if (Sw_Update!= TRUE)
  {
    for(i = 0; i< bytes ;i++)
    {
      Sw_Type [i] = *Ver_Value;     
      Ver_Value++;          
    }
    Sw_Update= TRUE;
  }
}

Это фрагмент моего кода, а "Ver_Value" - это структура, которая назначается в другой функции.

Итак, проблема, с которой я сталкиваюсь, заключается в том, что когда Sw_Update обновляется, Sw_Type [1] обновляется, и я вижу, что эти два имеют один и тот же адрес памяти.

Ответы [ 2 ]

0 голосов
/ 04 января 2019

static int Sw_Type []; составляет предварительное определение , согласно C 2018 6.9.2 2:

Объявление идентификатора для объекта, который имеет область действия файла без инициализатора,и без спецификатора класса хранения или со спецификатором класса хранения static составляет предварительное определение .Если модуль перевода содержит одно или несколько предварительных определений для идентификатора, а модуль перевода не содержит внешнего определения для этого идентификатора, то поведение точно такое, как если бы модуль перевода содержал объявление области файла для этого идентификатора с составным типом какконца единицы перевода, с инициализатором, равным 0.

Поскольку ваша программа не дает неумышленного определения, она выглядит так, как если бы она заканчивалась на static int Sw_Type [] = { 0 };.(Если из приведенного выше текста не ясно, что результат действительно является массивом из одного элемента, это становится понятным из Примера 2 в параграфе 5 того же пункта.)

Таким образом, Sw_Typeмассив из одного int.Он содержит только элемент Sw_Type[0].Поведение доступа к Sw_Type[1] не определено стандартом C.Из наблюдений, о которых вы сообщаете, кажется, что Sw_Update следует за Sw_Type в памяти, а доступ к Sw_Type[1] приводит к изменению Sw_Update.Это поведение, конечно, ненадежно.

Чтобы увеличить Sw_Type, вы должны объявить размер для него, как в static int Sw_Type[4];.

Примечание: 6.9.2 3 говорит: «Еслиобъявление идентификатора для объекта является предварительным определением и имеет внутреннюю связь, объявленный тип не должен быть неполным типом ». Хотя это может читаться как применение к объявленному типу в каждом объявлении, которое является предварительным определением, я думаю,он может быть предназначен для применения к объявленному типу объекта, как только его составной тип полностью разрешен в конце модуля перевода.Экспериментально Clang в порядке с принятием неполного типа сначала и завершением его позже.

0 голосов
/ 04 января 2019

Итак, проблема, с которой я сталкиваюсь, заключается в том, что когда обновляется Sw_Update, обновляется Sw_Type [1], и я вижу, что эти два имеют один и тот же адрес памяти.

Нет Sw_Type [1].Только массив с двумя или более элементами имеет вторую запись, и Sw_Type не является массивом с двумя или более элементами.Доступ к массиву за пределами может, конечно, помешать другим объектам.

...