0

I understand that arrays need to have a const int to be initialized, so I have this in main. I want this in main because I want to be able to modify these numbers easily if necessary.

const int magicWordCount = 10;
compareWords(magicWordCount);

The declaration of this function is:

void compareWords(const int);

The definition:

void Words::compareWords(const int magicWordCount)
{
std::string magic[magicWordCount] = {};
convertToStringArray(magicBuffer, magicBufferLength);
}

When I do this, "magicWordCount" in the definition is underlined by intellisense telling me, expression must have a constant value. I'm confused on where the value is NOT constant. Thoughts?

sntnmjones
  • 15
  • 9
  • magicWordCount is not a constant it is a parameter (or variable) with const access meaning that it can take on different numbers with each call to the function but is protected from change within the function. The standard way of creating arrays at runtime is to use std::vector (if you will resize) or std::array (if it will remain the same size). – T33C May 05 '16 at 21:09

3 Answers3

6

Although magicWordCount is const, as far as the compiler knows, it is a run-time constant, not a compile-time constant. In other words, it can ensure that the value of magicWordCount is not going to be changed inside Words::compareWords.

That is not enough to declare an array with the specific size: the compiler (and intellisense) are asking for a compile-time constant; magicWordCount is not a compile-time constant.

You can avoid this problem by using std::vector instead of an array:

std::vector<std::string> magic(magicWordCount);

The above will work even without const.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • We're not allowed to use vector. This is for an assignment. I'm not required to do the assignment this way, I just thought it would be a neat feature to have the const's easily accessible by putting them in main. – sntnmjones May 05 '16 at 20:53
  • Okay, I tried declaring magicWordCount by using: constexpr int magicWordCount = 10; but I'm still getting the same error. I'm not familiar with compile-time constants. :( – sntnmjones May 05 '16 at 21:03
  • 2
    You cannot pass in a value and make it a compile time constant. One call to the function could use 10 and another 100, changing the value of `magicWordCount` at run time. – user4581301 May 05 '16 at 21:05
  • So how does one go about passing a value to initialize an array? Or is it not good practice? – sntnmjones May 05 '16 at 21:18
  • @yorTsenoJ It would be a good practice if it were supported. However, the standard committee for C++ has repeatedly rejected the introduction of variable-length arrays into the language. They are available on some compilers as an extension, but using them makes your program non-portable. – Sergey Kalinichenko May 05 '16 at 21:37
  • 1
    If you cannot use a `vector`, the only portable solution is to `new[]` and `delete[]` an array. `std::string * magic = new string[magicWordCount];` This picks up a bunch of memory management because you must `delete[] magic;` when you are done with it. This can be tricky if exceptions are thrown or you have multiple exit points inside your function. [Fortunately C++11 has you covered.](http://en.cppreference.com/w/cpp/memory/unique_ptr) More here: [Is there any use for unique_ptr with array?](http://stackoverflow.com/questions/16711697/is-there-any-use-for-unique-ptr-with-array) – user4581301 May 05 '16 at 21:48
0

You could put magicWordCount in your Word class header, above your definition of the class. It's still easily accessible there, and you won't have to pass it in as a function parameter anymore.

-4

it is the problem about array because array is store in local scope which mean if it did not have a const size(define before compile) it could make buffer overflow attack for example the const int magicWordCount = 1000 the size of string[] will absolutely cover the return point so in this situation you might use pointer instead

string* str = (string*)malloc(sizeof(string*) * a);
for(int i = 0; i < a; i++){str[i] = "";}

and also for my opinion, never use array, and instead with pointer because the array perform really bad performance and a strange logic on read/write

Roy C
  • 25
  • 4
  • Do not do this. Do not do this in your nightmares. – user4581301 May 05 '16 at 21:16
  • `malloc`ing a `string` will only provide storage. It will not invoke the `string`'s constructor, and simply zeroing the `string` will not guarantee that the `string` is properly initialized. It might work, but it probably won't and certainly won't be a portable solution. There is a lot of stuff going on in a `string` and the right pieces must be in the right places to make that stuff happen. This should be assumed of any class unless you know specifically otherwise. Even then, prefer `new`. – user4581301 May 05 '16 at 21:33
  • oh sorry i get it wrong XD, it should not be memset(str, 0, sizeof(string*)* a);, i mean this for(int i = 0; i < a; i++){str[i] = "";}, it is because everytime i init a pointer, i will use memset, it just a mistake, i am not that mean XD, really sorry for this – Roy C May 05 '16 at 21:39
  • That fix is even more likely to blow up in your face. The solution is simple: Stop using `malloc`. Use `new` and allow the constructors to run. – user4581301 May 05 '16 at 21:42
  • unm~never mind, i know that malloc will not call the constructor, but i usually use malloc instead of new, because i learn C > C++, so it is hard to change the habit – Roy C May 05 '16 at 21:45
  • (a) `malloc` in C++ is broken. (b) `malloc`-ing a `std::string` is broken. (c) You `malloc`'d the wrong amount of memory. Absolutely no way this solution or anything resembling it passes code review in my organisation! – Lightness Races in Orbit May 05 '16 at 21:46
  • oh sorry, i think i have figure out what the problem is, my bad – Roy C May 05 '16 at 22:03
  • This is just bad advice all around. If you want to suggest a run time sized array then suggest a `std::vector`. In today's C++ there is basically no reason to use malloc and even the uses for new have been greatly diminished. – NathanOliver May 05 '16 at 23:35
  • in fact, the problem is that i make confused of class, so i using the malloc, the final solution of me should be string* str = new string[], BTW the main point of my solution is that don't use array in local, instead of a pointer, because pointer can point the memory outside the local scope, so that the size of array can be dynamic – Roy C May 06 '16 at 02:59