Неопределенная переменная при инициализации в операторе switch?

0

Сам вопрос требует явного ответа. В любом случае, здесь фрагмент моего кода...

    switch(cSet)...

    case 8:{ //Special Characters
        finalSet = special;
        char* charSet = new char[special.size() + 1];
        charSet[special.size()] = 0; //Append null terminator
        memcpy(charSet, special.c_str(), special.size());
        break;
    }

    case 9:{ //Alphnumeric and Special character
        finalSet = all;
        char* charSet = new char[all.size() + 1];
        charSet[all.size()] = 0; //Append null terminator
        memcpy(charSet, all.c_str(), all.size());
        break;
    }
    ...

Обратите внимание, что finalSet имеет тип std::string. Мне нужно сохранить его как массив символов. После этого оператора я вызываю charSet вне оператора switch:

    for(int i = 0; charSet; i++)
         printf("%s", charSet[i]);

Теперь очевидно, что операторы switch являются условными, поэтому переменная не всегда может быть объявлена. Поэтому Visual Studio 2012 бросает ошибку " charSet не определен". У меня есть оператор switch, но charSet всегда будет определен, или программа выйдет в случае по default.

Чтобы устранить эту проблему, я попытался объявить charSet вне области действия оператора switch. Однако, когда я это делаю, по какой-то причине компилятор выдает ошибку доступа к чтению.

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

Приветствуется любой конструктивный вклад.

Код ошибки при объявлении вне оператора switch:

'Unhandled exception at 0x0F6616B3 (msvcr110d.dll) in cuda_comb.exe: 0xC0000005: Access violation reading location 0x00000061.'
  • 0
    Пожалуйста, покажите другую ошибку в деталях. Вы должны объявить, что charSet увеличил размер оператора switch, как вы заявили.
  • 0
    Конечно, дай мне минутку ...
Показать ещё 9 комментариев
Теги:
switch-statement

4 ответа

2
Лучший ответ

Когда вы его вытащили, вы попробовали (перед переключением):

char* charSet = 0;

а затем во всех операторах switch удаляем char *, поэтому

char* charSet = new char[all.size() + 1];

будет выглядеть так:

charSet = new char[all.size() + 1];

то ваш код может даже проверить (после переключения):

if (!charSet)
{
  // handle odd case
}
  • 0
    Есть ли причина, по которой вы используете 0 а не NULL ?
  • 1
    @nonsensickle это C ++, а не C
Показать ещё 3 комментария
5
  1. Вы должны объявить charSet вне switch. Когда переменная объявляется внутри коммутатора/случая, она заканчивается, когда коммутатор заканчивается, даже если выполняется случай, объявляющий переменную.
  2. Для for(int я = 0; charSet; i++) циклы, пока charSet не равен 0 и каждый раз увеличивает i. Поскольку вы не меняете charSet внутри, для него всегда будет 0, так что в конечном итоге charSet[i] выходит за пределы и дает вам ошибку доступа к чтению. Измените его так, чтобы он проходил цикл до тех пор, пока i будет больше длины буфера, или charSet[i] == '0' (terminating-null). Например:

    for(int i = 0; charSet[i]; i++) 
        printf("%c", charSet[i]);
    
  3. Также измените %s в printf на %c когда вы печатаете char, а не char *. Хотя, поскольку вы все равно печатаете строку с завершающим нулем, вы можете полностью избежать цикла for:

    printf("%s", charSet);
    
2

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

Обратите внимание, что, делая это, если вы не использовали внешний блок блокировки charSet, вы не получите никакой ошибки, но вы будете пропускать память.

Я имею в виду:

switch(cSet)...

case 8:{ //Special Characters
    finalSet = special;
    char* charSet = new char[special.size() + 1]; // <-- charSet definition
    charSet[special.size()] = 0; //Append null terminator
    memcpy(charSet, special.c_str(), special.size());
    break;
} // <-- charSet reference lost, Memory leak

case 9:{ //Alphnumeric and Special character
    finalSet = all;
    char* charSet = new char[all.size() + 1]; // charSet definition
    charSet[all.size()] = 0; //Append null terminator
    memcpy(charSet, all.c_str(), all.size());
    break;
} // <-- charSet reference lost, Memory leak

} // End of switch

    for(int i = 0; charSet; i++)
     printf("%s", charSet[i]); // <-- Error charSet is not defined

Правильное решение для этого - объявить charSet вне оператора switch, чтобы вы не потеряли ссылку:

char* charSet = NULL;
switch(cSet)...

case 8:{ //Special Characters
    finalSet = special;
    charSet = new char[special.size() + 1];
    charSet[special.size()] = 0; //Append null terminator
    memcpy(charSet, special.c_str(), special.size());
    break;
}
...
}

if(charSet)
   printf("%s", charSet);

Обратите внимание, что при печати массива с "% s" вы можете напрямую использовать charSet.

  • 0
    Хм, ты тоже скопировал его ошибку. printf("%s", charSet[i]); должно быть printf("%c", charSet[i]); не так ли? Как и у вас нет условия остановки для цикла ... Попробуйте вместо for(int i = 0; charSet[i]; i++) .
  • 0
    @nonsensickle Пожалуйста, проверьте мое последнее обновление.
Показать ещё 2 комментария
0

Насколько я понимаю, ваш код выглядит так:

 switch(cSet){    
        case 8:{ //Special Characters           
           char* charSet  = new char[special.size() + 1];
           //code
           break;
          }
         case 9:{ //Special Characters           
           char* charSet = new char[all.size() + 1];
           //code
           break;
           }
        //other cases
     }

   for(int i = 0; charSet; i++)
         printf("%s", charSet[i]);

В этом случае, даже если вы определяете кодировку для каждого случая, вы ограничиваете область кодировки для каждого случая, где она определена, - которую вы уже определили и переместили объявление указателя за пределы переключателя - например:

char* charSet;
switch(cSet){    
       //code
}

Ошибка, которую вы получаете, в основном говорит о том, что вы читаете из недопустимой ячейки памяти. Это может произойти, если вы не назначаете указатель на динамически выделенную ячейку памяти. Несмотря на то, что вы, кажется, выделяете память для charSet для всех случаев инструкции switch, не забывайте, что у вас есть случай по умолчанию.

Надеюсь, поможет.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню