简体   繁体   中英

Is this a legal move to allocated a non-constant array?

I've created this code to solve some online answers which worked, but I was wondering if it is Okay to allocate dynamic memory this way. The array size is defined continuously throughout the loop. Is it okay?

#include <iostream>
using namespace std;

int main ()
{
    int sum=0;
    int x;
    int *ptr = new int[x];
    ptr[0]=1;
    ptr[1]=2;

    int max = 4000000;

    int i=2;

    while (ptr[i-2]<max)            
    {
        ptr[i]=ptr[i-1]+ptr[i-2];
        i++;
    }
    // now we use (i -1) as the last array fill b/c i is bigger than 4 000 000
    // sort with val % 2 == 0  !modulus!

    for (int j=0; j<(i-1); j++) {
        if (ptr[j]%2==0) {
            sum+=ptr[j];
        }
    }

    delete[] ptr;

    cout<<sum;
    return 0;
}

No, it's not okay, since int x; is uninitialized and may contain some garbage.
EDIT.
From comments to this post.
1) Use std::vector<int> instead of C-array.
2) If don't want use vector - add loop that count elements and then allocate memory for array and work with it.
3) Use static array of some big size if first and second cases not approach.

不,因为int x未初始化!

There are a number of problems with your code:

  1. x is not initialized to an initial value and so it may be some random value.
  2. The while loop uses ptr[i-2] < max which implies (i) there needs to be at least two array elements, ie, x must be set to a number no lower than 2 and (ii) < max is being comparing values in the array BUT there is no index check that i is between 2 and the number of array elements allocated with new . (When (ii) is coupled with i++ in the while loop, it means that i might keep increasing well past the end of the allocated array.

You need to set x to a correct value and add checks to ensure you never access any array indices < 0 or any indices >= x every in your code you access the ptr array.

Consider using std::vector instead if manually managing the memory yourself.

EDIT: It looks like your code intend to compute the Fibonacci sequence and do a sum of even numbers. To fix up your code, this is what should be done:

  1. Add #include <vector> .
  2. Delete int x;
  3. Delete int *ptr = new int[x]; and replace it with std::vector<int> v; .
  4. Replace ptr[0]=1 with v.push_back(1); .
  5. Replace ptr[1]=2 with v.push_back(2); .
  6. Replace the entire while loop.

Since it appears you are computing the Fibonacci sequence, you can loop using int i=2 in the initialization part of a for loop while v.back() < max adding one each time, ie, ++i . For loops are excellent to this with. Within the loop, you can v.push_back(v[i-1],v[i-2]); to compute the next number and append it to the array.

As for v.push_back(val) this adds val to the end of the vector (ie, the highest index) growing the vector (internally using dynamic memory) if required. v.back() is the last element of the vector, ie, equivalent to v[v.size()-1] only if v.empty() is false .

  1. Your comment mentions the for loop computing a larger value. However, your while loop does i-2 --not i-1 which is the second-to-last element --not the last element. Using std::vector it is easier to simply remove the last element if and only if it is >= 4000000. This can be handled using an if statement, ie, if (v.back() >= max) then v.pop_back(); .
  2. Adjust your for loop (ie, i should be v.size() ).
  3. Delete delete[] ptr; .

If you wanted to use dynamic memory allocation directly then the code would have to be written differently and would be more longer and complicated as you would have to be able to "resize" the array (which requires allocating more memory, copying the old contents into the new one, and then destroying the old one). Generally, however, you should use Standard Library containers and avoid directly managing memory. In this case std::vector is very well-suited to do this task using only a few lines of code.

As already noted, x is uninitialized when you try to use it as the size of array to allocate.

More importantly, however, at that point you don't really know how large of an array you'll need (I'm pretty sure it could be calculated, but we'll leave that for now).

Since you don't know the size up front, you pretty much need to allocate some space, produce some results, check the size, make more room of needed, and continue until you reach your target. Alternatively, you could do some really trivial math that would give a safe (if somewhat loose) estimate of the maximum size it could possibly. Since you're starting from 1, 2, and each cell will get larger than the previous, it's pretty safe to say that the maximum possible size needed will be no more than max/2 = 2000000 .

Alternatively, you could just use std::vector , which is already built to handle situations like this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM