3

Possible Duplicate:
Variable length arrays in C++?

I am trying to form an array whose size is governed by another variable fed in by the user. I am a beginner in C++ coding and I am using the visual studio 2008 professional compiler. This is the code where the compiler shows the error:

double kplus2(double a, double ks, double kr)
{
    int n = (ks-1)*100000;
    double x[n];

The error is

Error 2 error C2057: expected constant expression
Error 3 error C2466: cannot allocate an array of constant size 0
Error 4 error C2133: 'x' : unknown size

Community
  • 1
  • 1
Saahil
  • 49
  • 6

3 Answers3

14

I am trying to form an array whose size is governed by another variable fed in by the user.

C++ already has this functionality. It is called std::vector and lives in the header <vector>.

double kplus2(double a, double ks, double kr)
{
    int n = (ks-1)*100000;
    std::vector<double> x(n);
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
2

You'll need to dynamically allocate the memory, like this:

double *p = new double[n];

You can use it just like an array, since pointer syntax in C++ makes that convenient:

p[0] = 3.14;
p[n-1] = 1.14;

Once you're done using it, you must discard the memory using the delete operator:

delete [] p;

Note that we use the vector [] version of the delete operator since we used the vector version of the new operator.

Note that some compilers have an extension which allows dynamically sized local arrays like you tried to code. gcc is one such compiler. That's not a part of the language standard yet, though some day it might be.

MikeB
  • 1,452
  • 14
  • 28
  • 4
    -1 for `new[]` and `delete[]`. – Puppy Jan 02 '13 at 16:21
  • @DeadMG I'm curious as to why that's bad. – dutt Jan 02 '13 at 16:22
  • @dutt: [RAII](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization) – Mooing Duck Jan 02 '13 at 16:23
  • 2
    @dutt: Well, it's hideously unsafe in basically every way imaginable, for one thing. What's depressing is that anybody upvoted this terrible answer. – Puppy Jan 02 '13 at 16:23
  • 2
    @dutt This will work, but it introduces undesirable risk for absolutely no reward. An std::vector<> essentially does the same thing, but with the benefit of good RAII, etc. I wouldn't *down* vote this, as it will *technically* work; but there are *better* solutions. – WhozCraig Jan 02 '13 at 16:26
  • @Mooing Duck, WhozCraig, DeadMG: Thanks, learned something new today as well then :) – dutt Jan 02 '13 at 16:28
  • At the very least, you need to mention that it should be protected by a try-catch block. Though I disagree that it is unsafe in *every* way imaginable. For example, I don't think it will make my house more susceptible to hurricanes. – Benjamin Lindley Jan 02 '13 at 16:30
  • It will if you invoke UB. Then it's quite legal for an implementation to cause a hurricane to appear over your house. – Puppy Jan 02 '13 at 16:32
  • If the courts found out that some compiler author had the power to invoke hurricanes, I'm pretty sure it would be ruled illegal. – Benjamin Lindley Jan 02 '13 at 16:34
  • 1
    @BenjaminLindley Right before he was scooped up by the NSA. – WhozCraig Jan 02 '13 at 16:35
  • @DeadMG,@Benjamin or anybody:Why is it considered unsafe?I have used both pointer allocation and vector, but I was not aware of the security risks each had.Could you please explain? – Aravind Jan 02 '13 at 16:54
  • 2
    @Arivind: Using dynamic allocation with a pointer can be just as safe as using a vector, if done correctly. The problem is that doing it correctly is a lot more work. A single delete is not enough. You need to account for exceptions that might be thrown before the delete, otherwise it will not be executed, and you have a resource leak. With all that in mind, the issue becomes maintainability and readability. The vector is safe with a single line, its declaration. The pointer requires all that boiler plate to be safe, so why bother with it? – Benjamin Lindley Jan 02 '13 at 17:26
  • The whole new/delete thing kind blows it for me. At least wrap it in some type of strong pointer. – Captain Obvlious Jan 02 '13 at 17:47
  • @BenjaminLindley and that is *not enough*. There is also the issue of jump control flow, like `break`, `continue`, and more notably `return`. try/catch cannot handle those, which leaves you with convoluted code with obfuscated flow (SESE), and/or *gasp* resorting to `goto`. RAII just works. – R. Martinho Fernandes Jan 02 '13 at 19:55
1

You can use Vector. It can also be resized on run time so if you want to add more data, you won't have to worry about creating new array of desired size and copying the current data in that.

you can use vector & this is a better approach to solve your problem as it is less risky;

double kplus2(double a, double ks, double kr)
{
  int n = (ks-1)*100000;

  vector<double> x(n);  // you don't have to worry about deallocating it cuz its a container. It can grow in size at run time

  ...

 return 0;

}

However you can also do this:

double kplus2(double a, double ks, double kr)
{
  int n = (ks-1)*100000;

  double *x=new double[n]; // array of size i

  // you should also deallocate this dynamically allocated array at the end


  .....

  delete []x;

  return 0;

}

Alfred
  • 1,543
  • 7
  • 33
  • 45
  • For your second example, what if an exception is thrown between `new` and `delete`? It's fine to teach manual memory management, but please make sure to teach how it should be done properly. – Benjamin Lindley Jan 02 '13 at 17:28