1

i want to make my array more flexible. My input comes from a file. I get the information of how big my array needs to be from a function.

My Codesample looks like this:

int albumsize = getAlbumnumberFromFile(inputFile);
struct Album Alben[albumsize];

Now I have to following problem ... I can't do something like this. My IDE (Visual Studio 2017) says this Error:

expression must have a constant value

Thanks Alex

BlindRob
  • 23
  • 7
  • 3
    Well.. it looks like MSVC does not support VLAs. Another good reason to switch to some standard-compliant compiler. – Eugene Sh. Mar 19 '19 at 19:44
  • 1
    `struct Album *Alben = malloc(albumsize * sizeof *Alben); if(Alben) { /* use Alben */; free(Alben); } else { /* error */ }` – pmg Mar 19 '19 at 19:45
  • struct Album *Alben=(struct Album *)malloc(sizeof(struct Album)*albumsize); is what you use to get a dynamic array which has its size defined at runtime rather than compiletime. – Madhav Sarpal Mar 19 '19 at 19:48
  • Hmmm yeah MSVC seems to use a MS-C++ Compiler which don't offers VLA .. @pmg i can not use the struct Album as pointers because I would have to refactor all other functions because the "Read" / "Sort" Function are all implementet which Array operator like .releaseYear ..... – BlindRob Mar 19 '19 at 19:52
  • @BlindRob Pointers fully support the syntax that you use for array indexing, so switching to dynamic allocation would not lead to an issue. Moreover, arrays "decay" to pointers when passed to functions, so you wouldn't see much difference anyway. – Sergey Kalinichenko Mar 19 '19 at 19:54
  • Try it @BlindRob! Replace your `Alben[index].releaseYear` by mine `Alben[index].releaseYear` :) – pmg Mar 19 '19 at 19:54
  • @dasblinkenlight sorry I have troubles with the formatting ... so lets take this function as an example `void sortAlbenByYearASC(struct Album yourArray[], int arraysize) { struct Album tmp; for (int i = arraysize; i > 1; i--) { for (int j = 0; j < i - 1; j++) { if (yourArray[j].releaseYear > yourArray[j + 1].releaseYear) { tmp = yourArray[j]; yourArray[j] = yourArray[j + 1]; yourArray[j + 1] = tmp; } } } }` --> here I would have to replace transfer parameter to an pointer and also change the .releaseYear to an -> or? .. – BlindRob Mar 19 '19 at 20:09
  • In my case this would be a big change because I have like 15 functions around this struct[] - Array :-( – BlindRob Mar 19 '19 at 20:10
  • @BlindRob No, you would not have any problem passing a pointer for an "array" parameter because in C empty square brackets `[]` in parameter declaration denote a pointer anyway. Give it a try! – Sergey Kalinichenko Mar 19 '19 at 20:13
  • @dasblinkenlight ah thanks that's intressing was a nice transition .. arrays are nearlly the same as pointers ... :-) Learned alot and still standing there whit strange errors .. Project.exe has triggered a breakpoint. From this: `int testsize = 4; struct Album *Alben = malloc(testsize * sizeof(*Alben)); ReadFile(inputFile, Alben); printf("Unsorted Data: \n"); printAlben(Alben, testsize);` – BlindRob Mar 19 '19 at 21:06

3 Answers3

2

Although C standard allows variable-length arrays (VLA) Visual Studio compilers are not fully standard-compliant (relevant Q&A).

However, I would discourage use of VLA in this situation even if they were supported, because sufficiently large albumsize may lead to undefined behavior.

A better approach is to allocate memory dynamically, like this:

struct Album *Alben = malloc(albumsize * sizeof(*Alben));
... // Use the allocated memory here. Once you are done, free it.
free(Alben);

Note that one important difference between Alben-the-pointer and Alben-the-array is what you get from sizeof: array would report the size of its data, while pointer would report the size of the pointer alone. For that reason you need to keep the value of albumsize around - for example, for iterating the array in a loop.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

Microsoft does not support any remotely modern C standards. Variable Length Arrays were introduced in C99, but MSVC is still stuck on C89. You will need to either just create a statically-sized array large enough to hold whatever you may need, or malloc an array of the appropriate size.

Christian Gibbons
  • 4,272
  • 1
  • 16
  • 29
0

MSVC is not a C compiler. It is a C++ compiler with some C compatibility. As far as I know, Microsoft does not provide pure C compiler.

Since VLA (Variable length arrays) are not part of C++ standard, they are part of C standard (and optional even there) MSVC decided not to support them. You will have to use dynamic memory allocation for your array, which I admit is not very convenient.

SergeyA
  • 61,605
  • 5
  • 78
  • 137