0

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 ?

djfoxmccloud
  • 571
  • 1
  • 9
  • 23
  • 1
    Depends a bit on those ifs. If they can be evaluated at compile-time, then you can choose the length with template metaprogramming. – visitor Apr 04 '12 at 09:07
  • 1
    **Why** can't you use vectors? –  Apr 04 '12 at 09:10
  • @delnan: I have an idea: in Windows the STL is not suggested to be on any DLL interface. [Check this out!](http://msdn.microsoft.com/en-us/library/3tdb471s%28v=vs.80%29.aspx) – Naszta Apr 04 '12 at 09:21
  • @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? –  Apr 04 '12 at 09:36

5 Answers5

4

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;
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Ok i see. Then I will have to delete it after I use it. Do you know why this code worked on Linux and not in Visual on XP ? – djfoxmccloud Apr 04 '12 at 09:05
  • @visitor he can't use vectors, it's stated in the question (if you had read the whole thing). – Luchian Grigore Apr 04 '12 at 09:07
  • @djfoxmccloud it must be a gcc-extension, but it's not standard. – Luchian Grigore Apr 04 '12 at 09:07
  • 1
    @djfoxmccloud Probably because you didn't supply the necessary options for g++ to be a C++ compiler. By default, g++ compiles a language similar to, but not identical with, C++. Try adding `-std=c++98 -pedantic` if you want C++. – James Kanze Apr 04 '12 at 09:20
1

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);
Naszta
  • 7,560
  • 2
  • 33
  • 49
  • True, but that doesn't count in its favor if you ask me. Why do you think one would have to re-invent this wheel? –  Apr 04 '12 at 09:38
  • @delnan: to make clear: I would use `std::vector`. But as I read in the question, the poster does not like to use `std::vector`. I don't know why. In this case I suggest him a still good, but not STL based solution. – Naszta Apr 04 '12 at 09:41
  • Yes, given OP's requirements it's probably the best choice. I just hoped you had a plausible theory as to why OP crossed out vector. –  Apr 04 '12 at 09:42
  • The size of the `vector` object and the way of memory allocation (allocation class) could be changed between Visual C++ versions (including service packs). That's why STL is not suggested to be on DLL header interface (and runtime library also should not be there). So if you write an inline function for a class, and you want to use STL like container, usually it is easier to implement it. (And export it if it is necessary.) Because of these issues, I usually write DLL connected `new` and `delete` operators for inline functions. (Class sizes on dll interface also calculated from header.) – Naszta Apr 04 '12 at 09:48
0

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?)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
-2

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;
Benoch
  • 21
  • 1
  • C is not C++. What's idiomatic in C is discouraged to harmful in C++. Besides, your code is bad even in C (you [cast the result of malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)). –  Apr 04 '12 at 09:39
-3

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))
JoeG
  • 12,994
  • 1
  • 38
  • 63
Hiren H Patel
  • 167
  • 3
  • 12