Not Enough Array Size Problem



  • Hi guys

    I have a problem. I need big variable sizes.

    For examples;
    @ double array1[500000];
    double array2[500000];
    double array3[500000];
    double array4[500000];
    double array5[500000];
    double array6[500000];
    double array7[500000];
    double array8[500000];
    double array9[500000];
    double array10[500000];@

    When i run the program, I got "program has stopped working" problem. How can i do that?



  • I suggest you define your arrays as vectors, they allocate the array elements on the heap and not on the stack:

    std::vector<double> array1(50000);

    Now you can access this array in the same way like your previous arrays.


  • Lifetime Qt Champion

    Hi,

    How many arrays do you need ?

    Did you run your program through a debugger ?


  • Moderators

    What you've got is ~40Mb of stack space. The default maximums for most platforms/compilers are usually one order smaller.
    There are ways to increase it, but that just looks like a bad design. As PeerS said - go for dynamic allocation on the heap via Qt or STL containers or with just the plain new.



  • Thanks all of you guys.

    [quote author="PeerS" date="1367868404"]I suggest you define your arrays as vectors, they allocate the array elements on the heap and not on the stack:

    std::vector<double> array1(50000);

    Now you can access this array in the same way like your previous arrays.[/quote]
    I use the pointer variable and fix the problem. Is vector stronger than pointer?

    [quote author="SGaist" date="1367870712"]Hi,
    How many arrays do you need ?

    Did you run your program through a debugger ?[/quote]

    I need 8 arrays. Yes I run the debug mode.

    [quote author="Chris Kawa" date="1367872610"]What you've got is ~40Mb of stack space. The default maximums for most platforms/compilers are usually one order smaller.
    There are ways to increase it, but that just looks like a bad design. As PeerS said - go for dynamic allocation on the heap via Qt or STL containers or with just the plain new.[/quote]
    I didn't know that. It is a good knowledge. I use pointer variable and I fix the problem.


  • Lifetime Qt Champion

    No, a vector is not stronger than a pointer.

    What you have now is a pointer to a vector allocated on the heap rather than the stack. In short (and overly simplified), you moved your vector to another (and larger) memory space and the pointer is where you can access your vector in that space.

    Hope I don't confuse you



  • I am not sure what you mean with "I use the pointer variable ..", do you mean you create the array with new? If so, then you have to make sure you delete that array properly after use. If you use a vector (whether it is a std::vector or a QVector does not matter) then the vector object takes care of deleting the memory (this principle is called RAII; Google for it, it is good to understand what it means).

    Example:

    @
    void foo1()
    {
    double *pArray1 = new double[50000];

    // use your array here
    
    delete[] pArray1;
    pArray1 = nullptr;    // Note: nullptr is from C++11, if you do not use this, write: pArray1 = NULL;
    

    }
    @

    In the function foo1() I create an array with 50000 double values, I created it with new therefore the memory will be allocated on the heap. Then I use the array and after I am done using it I have to deallocate the memory again, I delete the array. Setting the pointer to 'nullptr' is not necessary but good practice.

    @
    void foo2()
    {
    std::vector<double> array1(50000);

    // use your array here
    

    }
    @

    In the function foo2() I again create an array with 50000 double values, however this time I use a std::vector<double>. I created the vector on the stack, however the memory which will hold the 50000 doubles will be allocated by the vector on the heap, it will do it without me having to take care of it, the vector will take care of that memory. The memory for the doubles will be allocated in one big chunck. After now using the array I do not have to explicetly delete it. The vector will be destroyed automatically at the end of the function foo, because I created it on the stack. The moment the vector gets destroyed it will then delete the memeory allocated on the heap automatically.

    So why is the second version better?

    • I do not have to take care of the lifetime of the array.
    • The moment the vector gets destroyed it will correctly deallocate all used memory, no way for me to mess this up, so less possibilities for bugs.
    • If during using the array an exception occures, then in foo1() the allocated memory will leak, while in foo2() the destructor of the vector will be called and the memory will be deallocated, no memory leak.
    • I can do much more with the vector, I can easily resize it, can clear it, can ask it for its current size and much more.

    Peer



  • @SGaist and @PeerS thanks for good posts. I am so glad. I am sorry to late reply. I have a final exams in university. They take my time a lot.

    I declare my variables with new operator and I delete them in the deconstructor function in the class. You right Vector is more useful. If I I delete the pointer in the wrong time, Program may crush. I change my code to Vector. I love Qt because If I have a trouble with something, People who like you help me how to fix.



  • Maybe you should pick a good c++ book before you continue to dive into the world of Qt?If you have times, try c++ primer 5 edition, if you are running out of time, try essential c++.

    Some supplement of the solution without vector and RAII--it is one of the solution of those old c programmers fascinated very much

    @
    void foo1()
    {
    //declare all of the variables from the start
    double *pArray1 = 0;
    double *pArray2 = 0;
    double *pArray3 = 0;
    double *pArray4 = 0;

    if(!(*pArray1 = (*double)malloc(sizeof(double)* 10000)) ||
       !(*pArray2 = (*double)malloc(sizeof(double)* 10000))){
        goto Catch;
    }
    
    //do something
    

    if(!(*pArray3 = (double)malloc(sizeof(double) 10000)) ||
    !(*pArray4 = (double)malloc(sizeof(double) 10000))){
    goto Catch;
    }

    //do something

    Catch:
    free(pArray1);
    free(pArray2);
    free(pArray3);
    free(pArray4);
    }
    @

    Although these codes considered to be a good coding style in c,it is like an anti-pattern in c++, and they wouldn't work well with c++ because c++ may throw exception, make use of RAII(like vector) is far more better than leaving the resource to raw pointer in c++.No matter how much praise and love of those c programmers mention about this coding style, you better stick with RAII if you want to save yourself from troubles in c++.

    ps : RAII is a resource management techniques of c++, it is extremely useful and versatile. In a simple word, RAII equal to "let object manage the resource", this is a recommend coding style of modern c++.

    Some(or many?) c(even c++) programmers said RAII need more space and slower than raw pointer, is this true?I would say this depends on your design

    ex :

    @
    //a naive design
    class roughRAII
    {
    public:
    roughRAII(double *data) : data_(data) {}

    ~roughRAII() { delete []data_; }
    

    private:
    double *data_;
    };
    @

    "RAII":http://www.hackcraft.net/raii/

    This class do not ask for more space than a single raw double pointer, As this class have inline non-virtual constructors and destructors the code produced by an optimising compiler should be pretty much identifcal to that of the equivalent using explicit resource acquisition and release.


  • Moderators

    I don't think you should mention malloc and goto to someone who's just learning C++. Those are things from an ancient past and should be left in history books.
    There's also rarely a need for specialized RAII adapter. C++ already provides those.

    In C++11 you can just write
    @
    unique_ptr<double[]> arr(new double[500000]);
    //do something with arr
    @
    Also, C++14 is around the corner, and with it you won't(and rarely should) even see new :
    @
    auto arr = make_unique<double[]>(500000);
    //do something with arr
    @
    If you can't use C++11, but do use Qt, there are also Qt versions of safe pointers, eg.:
    @
    QScopedPointer<double, QScopedPointerArrayDeleter<double> > arr(new double[500000]);
    //do something with arr
    @
    In any case you don't need to worry about releasing resources or exception handling.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.