In the code below, the compiler emphasizes the second array index, [ColCount], and writes: the expression must have a constant value. Tell me what is the error and how to fix it?

const int RowCount = Height(Root); const int ColCount = (2 << RowCount) - 1; char *TreeArray; TreeArray = new char[RowCount][ColCount]; 
  • 3
    So what about std::vector ? - AnT
  • Yes, really the best option. Thank. - Georgiy_

2 answers 2

 char *TreeArray; 

This pointer is like a one-dimensional array.

 TreeArray = new char[RowCount][ColCount]; 

And this doesn’t look like a one-dimensional array ...

to implement a dynamic array of strings with a dimension defined in run-time?

 char **a = new char * [n]; for (size_t q=0; q<n; ++q) a[q] = new char [m]; ... for (size_t q=0; q<n; ++q) delete [] a[q]; delete [] a; 
  • Thank. But do not tell me how you can implement a dynamic array of strings with a dimension defined at run-time? - Georgiy_
  • @Georgiy_, wrote about (I hope I was not mistaken, did not check). - Qwertiy
  • @Qwertiy The construction is correct. Under certain restrictions - see my answer. - Harry
  • @Harry, corrected the answer. - Qwertiy

Since the answer to the question itself was not given (that "the expression must have a constant value" ), I will explain ...

The compiler has not yet begun to understand what you select, what type, and how you can assign it later - your type is incorrectly declared, but this is the second question. While he is looking at new char[RowCount][ColCount] . And since the design

 new char[A][B] 

quite workable in C ++ (see, for example, http://ideone.com/bJeaHF , you just need to understand what it does and what restrictions are placed on it), then it starts to deal with it. What does she do? It allocates memory for A arrays of size B , except that size B must be a compile-time constant. Then it can be rewritten in a familiar and more understandable form:

 using str = char[B]; new str[A]; 

It is a constant restriction among arrays :) Recall, for example, that a two-dimensional array can be passed to a function — but only the second dimension should be a compile-time constant. So here. But! Your constants, although described as const , are runtime constants - they cannot change after initialization, but they are unknown during compilation - because of the calculation of Height(Root) - is this not a constexpr - a function of the constexpr ? :)

So they point to this sad fact that at compile time the value of ColCount unknown ...

  • Thank you. I thought that the dimension of a dynamic array could be calculated at run time. Was wrong. - Georgiy_
  • @Georgiy_ Well, there are enough exits :), but ... How will you apply to it if you highlight? How does the compiler understand when you refer to a[n][m] , say? How to count? There is a pointer, you need to find the offset n*ColCount+m . How? Where to store ColCount , if there is only a pointer ? But if the second dimension is known at compilation, then it may well calculate such an offset ... - Harry
  • But when creating dynamic objects, isn’t memory allocated on the heap? And it does not stand out at compile time, but at run time. And there the appeal to the elements is already the concern not of the compiler, but of the heap manager. - Georgiy_
  • @Georgiy_ Appeals to the elements of an array are performed through pointer arithmetic. a[5] == *(a+5) . When allocating char[A][B] allocate a piece of memory A*B bytes in size. All that you have is a pointer. How do you charge, having a pointer to the beginning of this piece a , the element a[n][m] ? Whether the compiler, the memory manager (and he has to do with it?) - it does not matter. What is this symbol in which memory cell is located in the beginning of the block? - Harry
  • n * ColCount + m as you wrote before. I understand that I am mistaken, but I still do not understand why. After all, at the time when the memory is allocated, the value of ColCount is already known. - Georgiy_