Сам вопрос требует явного ответа. В любом случае, здесь фрагмент моего кода...
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.'
Когда вы его вытащили, вы попробовали (перед переключением):
char* charSet = 0;
а затем во всех операторах switch удаляем char *
, поэтому
char* charSet = new char[all.size() + 1];
будет выглядеть так:
charSet = new char[all.size() + 1];
то ваш код может даже проверить (после переключения):
if (!charSet)
{
// handle odd case
}
0
а не NULL
?
charSet
вне switch
. Когда переменная объявляется внутри коммутатора/случая, она заканчивается, когда коммутатор заканчивается, даже если выполняется случай, объявляющий переменную. Для 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]);
Также измените %s
в printf
на %c
когда вы печатаете char
, а не char *
. Хотя, поскольку вы все равно печатаете строку с завершающим нулем, вы можете полностью избежать цикла for
:
printf("%s", charSet);
Вы определяете 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
.
printf("%s", charSet[i]);
должно быть printf("%c", charSet[i]);
не так ли? Как и у вас нет условия остановки для цикла ... Попробуйте вместо for(int i = 0; charSet[i]; i++)
.
Насколько я понимаю, ваш код выглядит так:
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, не забывайте, что у вас есть случай по умолчанию.
Надеюсь, поможет.