20

I am using some existing code that someone else has written, and I cannot get it to compile (limited C experience here but I am trying to learn!).

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);
}

Here is the error.

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

The error on line 251 refers to

char *filename1 = new(char[filenameLength]);

If you need any additional information let me know please.

akappa
  • 10,220
  • 3
  • 39
  • 56
user1509364
  • 201
  • 1
  • 2
  • 3

3 Answers3

32

The error is correct. VLA(variable size arrays) are forbidden in C++. This is a VLA:

char filename1char[filenameLength];

What you probably meant is this:

char *filename1 = new char[filenameLength];

Which is not a VLA, but an array of chars allocated on the heap. Note that you should delete this pointer using operator delete[]:

delete[] filename1;
mfontanini
  • 21,410
  • 4
  • 65
  • 73
17

Try this instead

    char *filename1 = new char[filenameLength];

you cannot create an array as a local variable length array on the stack like this

    char filename1[filenamelength];

unless filenamelength is declared as const.

Also as you have allocated memory for an array, you should free the memory using

   delete [] filename1;

otherwise you will have a memory leak. Also it is not essential to have parentheses around your return values;

mathematician1975
  • 21,161
  • 6
  • 59
  • 101
3

They are forbidden, but a workaround is to use a stack allocator, for example:

http://howardhinnant.github.io/stack_alloc.html

You can use the stack allocator with a ::std::vector (or with some other container, or just directly) and you've got yourself a VLA.

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
user1095108
  • 14,119
  • 9
  • 58
  • 116