Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Pointers and object initialization



  • Hello C++ Gurus,
    As a very beginner C++ hobby developer (might not make any sense but I hope you get the idea), I have questions about pointers and hwo to use them when an object is initialzed.

    As far I understand, pointers are used to avoid memory leaks, so they have to used as often as possible.
    So here is the code sample I'm working on:

    QJsonDocument* httpService::getAll(QString *url)
    {
        int pageNumber = 0;
        bool isLast = false;
        QJsonArray *allPagesArray = new QJsonArray();
        QJsonObject *infos = new QJsonObject();
    
        do {
            QString *requestUrl = new QString(url->append(QString::number(pageNumber)));
            QJsonDocument *objectList = new QJsonDocument(get(*requestUrl));
    
            if(objectList->object()["content"].isNull()) {
                break;
            }
    
            allPagesArray->append(objectList->object()["content"]);
    
            isLast = objectList->object()["last"].toBool();
            pageNumber++;
    
            if(isLast == true)
            {
                infos->insert("totalPages", objectList->object().value("totalPages"));
                infos->insert("totalElements", objectList->object().value("totalElements"));
                infos->insert("size", objectList->object().value("size"));
                allPagesArray->append(*infos);
            }
    
        } while(!isLast);
    
        QJsonDocument *allPagesJsonDoc =  new QJsonDocument(*allPagesArray);
    
        return allPagesJsonDoc;
    }
    

    Firstly, I don't know how to get 'pageNumber' and 'isLast' (which are primitives), I don't even know if it is necessary.

    Secondly, I've manage to turn every other variables into pointers but I quite sure that they are not destroyed automatically (when they go out of scope for example). So how can I manage that ?

    I know that the pointers subject is very large and complex so if you have some documentation or video or whathever recommandation that I could get, feel free to share (I've already read and take some C++ course/documentation but I still have difficulties to fully understand pointers).

    Thanks for reading.


  • Qt Champions 2019

    @Aymeric_Qt said in Pointers and object initialization:

    pointers are used to avoid memory leaks, so they have to used as often as possible

    Actually pointers are a source for memory leaks :-) To be more precise: heap allocation is source for memory leaks.
    You should use stack allocation as much as possible and only use pointers (heap allocation) when needed.
    Stack allocation:

    void someFunction()
    {
        SomeObject obj;
        obj.doSomething();
    }
    

    obj is automatically deleted as soon as someFunction() finishes!

    Heap allocation with pointer:

    void someFunction()
    {
        SomeObject *obj = new SomeObject();
        obj->doSomething();
    }
    

    obj is NOT deleted when someFunction() finishes - you have to explicitly delete it using "delete"!
    You see - using stack allocation in this example you can't create a memory leak, but you can when using heap allocation.

    Also stack allocation is way faster than heap allocation.


  • Lifetime Qt Champion

    Hi,

    First thing: turning everything to pointers is not a goal of good C++ programming.

    In the case of your code snippet, you are leaking every object you created because you did not properly destroy them using 'delete'.

    You should take a look at the examples of QString and the QJsonXXX, you won't see any use of pointers for them because it's not required. Like all the container classes, you will rarely see them allocated on the heap even if internally, that's what they do.



  • Hi @SGaist,

    "First thing: turning everything to pointers is not a goal of good C++ programming."
    Too bad I was almost there... :)

    So how do I know what need to be pointers and doesn't need to be ?


  • Lifetime Qt Champion

    It will all depend on the data you are going to use, how you are going to use it and depending on the types you are using how you are going to pass them around.

    There's not one final answer because, well, as I wrote above, it depends.



  • @Aymeric_Qt said in Pointers and object initialization:

    Hi @SGaist,

    "First thing: turning everything to pointers is not a goal of good C++ programming."
    Too bad I was almost there... :)

    So how do I know what need to be pointers and doesn't need to be ?

    So you are a beginner, I have a strong advice for you:
    Stay away from pointers as much as possible.
    In 99% of cases they are useless.

    You need to allocate with new for all the QWidgets in Qt, but If you follow carefully the Qt object memory management (parent/child model) you only need to delete the top level objects (windows) and Qt delete all the children in the object tree for you automatically.

    You need to use pointers when you have to allocate dynamically a block of memory, for example, to load raw data from a file.
    Even in this case, Qt provide QByteArray, so you don't need to allocate memory by yourself.

    And for functions parameters, avoid pointers too, use references instead.

    Have fun with Qt :)



  • @SGaist said in Pointers and object initialization:

    It will all depend on the data you are going to use, how you are going to use it and depending on the types you are using how you are going to pass them around.

    There's not one final answer because, well, as I wrote above, it depends.

    Ok but there must be some rules (so now I need to know how/where do I learn that, I'll continue my resarch).

    @mpergand said in Pointers and object initialization:

    So you are a beginner

    Yes I am! :)

    @mpergand said in Pointers and object initialization:

    @Aymeric_Qt said in Pointers and object initialization:
    You need to allocate with new for all the QWidgets in Qt, but If you follow carefully the Qt object memory management (parent/child model) you only need to delete the top level objects (windows) and Qt delete all the children in the object tree for you automatically.

    What about widgets (like button, lie edit etc..) added in the Qt Creator Design mode, are they automatically parented ?
    Add what about other classes. When I create a class (a service for example) by default, as I understand, it have no parent givent that the constructor, in the header file, look like this:

    explicit httpService(QObject *parent = nullptr);
    

    So will it be destroyed too when the application get closed ?



  • Have a look at:
    https://doc.qt.io/qt-5/objecttrees.html

    So will it be destroyed too when the application get closed ?

    In modern computer, each process runs in its own memory space. This space returns back to the system when the process terminates.

    explicit httpService(QObject *parent = nullptr);
    

    In this case you are responsible for deleting the object when you no longer need it. Actually it's what we call "top level widget" like QMainWindow or QDialog, and for them you can set Qt::WA_DeleteOnClose to true for this widgets to be deleted when closed.

    One strongly recommend to use QScopedPointer, smartPointer etc for safety. It's up to you to use them.



  • Oooohhhh...this could be a fun hornet nest to poke.

    Pointers are not evil...there are just too many people who thought software engineering would be an easy field such that too many practicing SEs are afraid of them so they attempt to dumb down the whole discipline with sometimes ridiculous safety rules.


  • Qt Champions 2019

    @Aymeric_Qt said in Pointers and object initialization:

    pointers are used to avoid memory leaks, so they have to used as often as possible

    Actually pointers are a source for memory leaks :-) To be more precise: heap allocation is source for memory leaks.
    You should use stack allocation as much as possible and only use pointers (heap allocation) when needed.
    Stack allocation:

    void someFunction()
    {
        SomeObject obj;
        obj.doSomething();
    }
    

    obj is automatically deleted as soon as someFunction() finishes!

    Heap allocation with pointer:

    void someFunction()
    {
        SomeObject *obj = new SomeObject();
        obj->doSomething();
    }
    

    obj is NOT deleted when someFunction() finishes - you have to explicitly delete it using "delete"!
    You see - using stack allocation in this example you can't create a memory leak, but you can when using heap allocation.

    Also stack allocation is way faster than heap allocation.



  • Hi @jsulm,

    @jsulm said in Pointers and object initialization:

    Actually pointers are a source for memory leaks :-) To be more precise: heap allocation is source for memory leaks.
    (...)
    Also stack allocation is way faster than heap allocation.

    Once again I realise that I got it all wrong :D. I really thought that pointers were used for performances because it allows to avoid to copy object (so it was faster).

    And what about the infamous stack overflow? Is it still a chance this can happen (without an obvious error like allocate a thousand of objects on the stack at the same time) ?
    Because I have the feeling that it can goes quite fast when you have a more complex application, if you take in account all the interface widgets (buttons, line edit etc..) plus a few other classes like services etc...



  • @Aymeric_Qt said in Pointers and object initialization:

    Once again I realise that I got it all wrong :D. I really thought that pointers were used for performances because it allows to avoid to copy object (so it was faster).

    No, you got it right. pointer access to memory can be substantially faster than other methods like array indexing.

    *(ptr++) is generally faster than v=array[n];
    // where simply iterating through memory; yes some
    // std::algorithms can duplicate this behaviour, but they will
    // invariably use the pointer aproach themselves

    And what about the infamous stack overflow? Is it still a chance this can happen (without an obvious error like allocate a thousand of objects on the stack at the same time) ?

    Yes...stack overflow should be considered. there is no one size fits all with regard to stack vs heap storage. each has appropriate use and misuse.

    Because I have the feeling that it can goes quite fast when you have a more complex application, if you take in account all the interface widgets (buttons, line edit etc..) plus a few other classes like services etc...

    and don't confuse heap allocation and pointers. they are NOT the same thing. in heap allocation you reference data through a pointer, but a pointer can point to ANY ADDRESS or piece of data. So, pointer is a lower level method of accessing memory than a variable is.

    int local() {
    int myVar{ 34 };
    int* varPtr{ &myVar };    // points to stack location of myVar
    int* heapVar = new int[50]; 
    // heapVar is pointer to first elem of array on the heap
    }
    

  • Qt Champions 2017

    @Kent-Dorfman said in Pointers and object initialization:

    No, you got it right. pointer access to memory can be substantially faster than other methods like array indexing.

    *(ptr++) is generally faster than v=array[n];

    Eh, that one's hard to prove. Consider this simple snippet, it's not easy to judge which is faster. For one, the array indexed piece is SIMD optimized.

    and don't confuse heap allocation and pointers. they are NOT the same thing. in heap allocation you reference data through a pointer, but a pointer can point to ANY ADDRESS or piece of data. So, pointer is a lower level method of accessing memory than a variable is.

    Correct, and as such is an indirection by merit of its construction, which more often than not also means a cache miss if locality isn't good. The point is that pointers ain't all moonlight and roses, as you make it sound. I'd rather agree with your statement that it depends on the use case!

    A decent enough hornets' nest for your taste? :)



  • Hey,
    Sorry for the delay, I didn't had/take enough time for Qt these days.

    I think this is going a little bit far/too complex for me at the moment. I need to learn and pratice more on pointers.
    Also my question was too 'general' so it could not be really answered (except with a all disseration and that was not the goal). But I've learn some really usefull informations and that's already something!

    So thank you all for your replies.

    Have a nice day.


Log in to reply