0
votes

I am trying to assign an array of unsigned short depending on a condition. The problem I encounter is the following (according to the code below) :

error C2057: constant expression expected
error C2466: impossible to allocate array with constant size 0
error C2133: 'packet' : unknown size

unsigned int length=4;
if(...)
{
    length = 8;
}
else if(...)
{
    length = 6;
}
else
{
    length = 4;
}

unsigned short packet[length/2];

I tried to do some shenanigans like adding this before the array declaration and using it for the array size but it doesn't do the trick:

const unsigned int halfLength=length/2;

I can't use vectors to replace my array. Do you have any idea ?

5
Depends a bit on those ifs. If they can be evaluated at compile-time, then you can choose the length with template metaprogramming. - visitor
Why can't you use vectors? - user395760
@delnan: I have an idea: in Windows the STL is not suggested to be on any DLL interface. Check this out! - Naszta
@Naszta I don't see how that applies here. Is there any indication OP is building a DLL and would have to inherit from vector to use it? - user395760

5 Answers

4
votes

Yup, dynamically allocated arrays:

unsigned short* packet = new unsigned short[length/2];

You can't specify the size of an automatic-storage allocated array at run-time.

You also have to free up the memory yourself:

delete[] packet;
0
votes

The number of elements in a C style array must be an integral constant expression in C++. (C90 has some support for non-constant expressions here, but I'm not familiar with it.) The obvious answer is std::vector, but you say you can't use that. If that's the case, you probably can't use dynamic allocation either; otherwise, a pointer and new unsigned short[length / 2] can be used, although you'll have to ensure that a delete[] also occurs when your done with it, including if you leave scope via an exception—in the end, you're not far from having implemented about half of std::vector locally.

If your code extract isn't too simplified: why not just reserve the maximum length, e.g.:

unsigned short packet[8 / 2];

In your example, the largest length is 8, and always reserving for 8 isn't going to cause any problems. (Obviously, if the actual length can vary more with values coming from an external function, etc., this may not be a realistic solution. But if it is... Why do complicated when you can do simple?)

0
votes

I would take it to a class to avoid memory leaks:

template <class T1> class array
{
public:
  array( size_t size )
    : addr(0)
  {
    if ( size > 0 )
      this->addr = new T1[size];
  };
  ~array( void )
  {
    if ( this->addr != 0 )
    {
      delete [] this->addr;
      this->addr = 0;
    }
  };
  T1 & operator[]( size_t index )
  {
    return this->addr[index];
  };
  bool empty( void ) { return (this->addr != 0); };
private:
  T1 * addr;
};

array<unsigned short> packet(length/2);
-2
votes

for c programmers:

//length value is dynamically assigned
int length=10;

//runtime allocation
unsigned short * f = (unsigned short *) malloc (length/2 * sizeof(unsigned short));

//use the vector
f[0]=1;

...

//free the memory once the program does not need more
free(f);
f=NULL;
-3
votes

You cannot assign the size of array dynamically. You can use a pointer for allocating dynamic size of array.

int * t = malloc(a * sizeof(int))