С++ запрещает массив переменных размеров
Я использую какой-то существующий код, который написал кто-то другой, и я не могу его скомпилировать (ограниченный опыт C здесь, но я пытаюсь учиться!).
utilities.cc
#include "utilities.h"
FILE *open_file(char *filename, const char*extension, const char *access)
{
char string[MAX_STR_LEN];
FILE *strm = NULL;
if(filename[0]=='\0')
{
printf("\n INPUT FILENAME (%s) > ",access);
fgets(string,MAX_STR_LEN,stdin);
sscanf(string,"%s",filename);
printf(" FILE %s opened \n", filename);
}
int len=strlen(filename);
if( len + strlen(extension) >= MAX_STR_LEN)
{
printf("\n ERROR: String Length of %s.%s Exceeds Maximum",
filename, extension);
return(NULL);
}
// char *filename1 = new(char[len+strlen(extension)+1]);
const int filenameLength = len+strlen(extension)+1;
char *filename1 = new(char[filenameLength]);
strcpy(filename1,filename); // temp filename for appending extension
/* check if file name has .extension */
/* if it does not, add .extension to it */
int i=len-1;
while(i > 0 && filename[i--] != '.');
// printf("\n Comparing %s to %s", extension, filename+i+1);
if(strcmp(extension, filename+i+1) )
strcat(filename1,extension);
if( (strm = fopen(filename1, access) ) == NULL )
{
printf("\n ERROR OPENING FILE %s (mode %s)", filename1,access);
}
delete(filename1);
return(strm);
}
Вот ошибка.
Compiling utilities.cc ...
src/utilities.cc: In function ‘FILE* open_file(char*, const char*, const char*)’:
src/utilities.cc:251: error: ISO C++ forbids variable-size array
gmake: *** [/home/landon/geant4/work/tmp/Linux-g++/exampleN01/utilities.o] Error 1
Ошибка в строке 251 относится к
char *filename1 = new(char[filenameLength]);
Если вам нужна дополнительная информация, сообщите мне.
Ответы
Ответ 1
Ошибка правильная. VLA (массивы с переменным размером) запрещены в С++. Это VLA:
char filename1char[filenameLength];
Что вы, вероятно, имели в виду:
char *filename1 = new char[filenameLength];
Это не VLA, а массив char
, выделенный в куче. Обратите внимание, что этот указатель следует удалить с помощью оператора delete[]
:
delete[] filename1;
Ответ 2
Попробуйте это вместо
char *filename1 = new char[filenameLength];
вы не можете создать массив как локальный массив переменной длины в стеке, как этот
char filename1[filenamelength];
если filenamelength
не объявлен как const
.
Также, как вы выделили память для массива, вы должны освободить память, используя
delete [] filename1;
в противном случае у вас будет утечка памяти. Также не обязательно иметь круглые скобки вокруг ваших значений return
;
Ответ 3
Они запрещены, но обходным путем является использование распределителя стека, например:
http://howardhinnant.github.io/stack_alloc.html
Вы можете использовать распределитель стека с ::std::vector
(или с каким-либо другим контейнером или просто напрямую), и у вас есть VLA
.