1

I want to have two arrays A and B where A=[a0, a1, a2, …, aN-1], B=[b0, b1, b2, …, bN-1] where "N" would be an input from the user. I wanna fill both arrays with random numbers between 0 and 1. Then I wanna have the product of aN and bN in an array C[n], also I want the summation of the elements in array C. I am not sure what I'm doing wrong but the application runs fine until I enter a number like 100,000 as N, if I enter some big number like this the application will crash.

Here is my code in C++:`

int main(int argc, char **argv)
{
  long long int n;
  cout << "Hi, what do you want n to be?\n";
  cin >> n;
  long long int c = n - 1;

  double A[c], B[c], C[c];
  srand(time(NULL));

  for (long long int i = 0; i <= c; i++) {
    A[i] = ((double) rand() / (double) (RAND_MAX));
    B[i] = ((double) rand() / (double) (RAND_MAX));
    C[i] = (double) A[i] * B[i];
    printf("%d  %.15f\n",i, C[i]);
  }
  double sum = 0;
  for (long long int i = 0; i <= c; i++){
    sum += C[i];
  }
  printf("%d", sum);
  return 0;
}
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Agon Cecelia
  • 33
  • 1
  • 7
  • 3
    *double A[c], B[c], C[c];* -- This is not valid C++. Arrays must have constant expressions to denote the number of entries. If you used `std::vector`, which is standard C++, you would not have the issue you're reporting (or at least, one issue you know about wouldn't occur). – PaulMcKenzie Oct 26 '16 at 22:21
  • @PaulMcKenzie, Dynamic array allocated on the stack are perfectly legal in C++14. http://blog.smartbear.com/development/a-glimpse-into-c14/ – Alexis Wilke Oct 26 '16 at 23:17
  • 1
    @AlexisWilke [See this](http://stackoverflow.com/questions/20777623/what-is-the-status-on-dynarrays) – PaulMcKenzie Oct 26 '16 at 23:29
  • 1
    **dcl.array** in the standard seems to disagree with you, @AlexisWilke. – user4581301 Oct 26 '16 at 23:29

3 Answers3

4

One issue is this:

double A[c], B[c], C[c];

This is not valid C++, as arrays must have constant expressions to denote the number of entries. You're using an extension offered by your compiler, namely Variable Length Arrays (VLA). The issue is more than likely you're blowing out the stack space due to the arrays being too large.

Instead of this, use something that is valid C++, namely std::vector:

long long int n;
cin >> n;
long long int c = n - 1;
std::vector<double> A(c), B(c), C(c);

However, please note that a std::vector is limited to std::vector::max_size() elements, thus it is possible that the value you enter for n may be too large to store the elements. Reconsider whether you want to go beyond the max_size() value.


In addition, you are accessing elements out of bounds. This is another area where using std::vector is advantageous over arrays.

for (long long int i = 0; i <= c; i++) {
    A.at(i) = ((double) rand() / (double) (RAND_MAX));
    B[i] = ((double) rand() / (double) (RAND_MAX));
    C[i] = (double) A[i] * B[i];
    printf("%d  %.15f\n",i, C[i]);
}

You will see that when i == c, the call to A.at() is guaranteed to throw an std::out_of_range exception, denoting that you have gone out of bounds with the index i. An array cannot report errors like this with any consistency, as going out-of-bounds of an array is undefined behavior (the code may "work", may crash, etc.).


There is another issue, and it's this:

  printf("%d", sum);

Since sum is a double, giving printf a variable type that does not match the format specifier is undefined behavior. More than likely, you will see wild numbers being printed. The format specifier, %d, requires an int type, not a double. So the correction would be this:

  printf("%lf", sum);

But since you're using C++, you should simply use std::cout, as it is typesafe and will not have you get into this type of trouble:

  std::cout << sum;

When you remove all of the errors and make the corrections describe, here is a live example showing the output.

In addition, here is an alternative that uses the STL algorithm functions that is much shorter than the code you have now, and does not need to declare 3 vectors (only one vector needs to be declared):

Example using STL algorithms

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • You may want to be more precise when you say "not valid C++". The post is somewhat about C and C++, and since C++14, it is perfectly legal. It also was working in Visual C++ for ages. http://blog.smartbear.com/development/a-glimpse-into-c14/ (see "Runtime-Sized Arrays" section.) – Alexis Wilke Oct 26 '16 at 23:19
  • [`dynarry` was not accepted into the standard](http://stackoverflow.com/questions/20777623/what-is-the-status-on-dynarrays) – PaulMcKenzie Oct 26 '16 at 23:27
  • Not a whole lot of `std::cout` in C, @AlexisWilke – user4581301 Oct 27 '16 at 00:05
3

When you have an array of size c, you can access elements 0 through c-1, not c!

So your loop should be

for (long long int i = 0; i < c; ++i)

instead of

for (long long int i = 0; i <= c; ++i)

Also, for a large c consider using heap memory instead of stack memory, e.g. use

A = new double[c];

instead of

double A[c];

Further, get familiar with smart pointers such as std::unique_ptr and STL containers such as std::vector.

Donghui Zhang
  • 1,133
  • 6
  • 8
  • 1
    The index type should be `size_t` instead of `long long int`. – Dai Oct 26 '16 at 22:28
  • @Dai, `c` is a `long long int`, though. – Alexis Wilke Oct 26 '16 at 23:20
  • `c` probably shouldn't be, though. For example input of -1. `c` is now -2. `i` starts at zero. Going to take a loooong time to reach -2 and generate a hilariously wrong answer if the undefined behavour from stomping memory outside of `A`, `B`, and `C` doesn't kill the program first. OP's whole algorithm needs a rethink – user4581301 Oct 27 '16 at 00:04
1

Besides that you are running out of array bounds, due to "i<=c" you are running out of stack space: The arrays are placed on stack and the size on stack is limited. Exceeding the stack size your program will crash. Default stack size depends on OS and OS settings. On Linux you can change it using "ulimit -s".

Meixner
  • 615
  • 5
  • 8