Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. I need to copy a QString every time it is used?
Forum Updated to NodeBB v4.3 + New Features

I need to copy a QString every time it is used?

Scheduled Pinned Locked Moved General and Desktop
15 Posts 6 Posters 5.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    primem0ver
    wrote on last edited by
    #1

    Perhaps I am missing something basic about references/pointer translation but please explain to me why the following code doesn't work... (the QDir overload I am using is QDir(QString&)

    @
    // from header file
    class A
    {
    ...
    public:
    void assignBaseDir();
    private:
    QString mBaseFolder;
    QDir
    mBaseDir
    }

    // from cpp file:
    A::assignBaseDir()
    {
    mBaseDir = new QDir(*mBaseFolder); // throws a memory access violation!
    }
    @

    EDIT: FYI: It might help to know that mBaseFolder is initialized with a QString allocated on the stack in the main executable while the A class is located in a separate dll. If I copy the QString to a new QString in A's constructor it works fine. However, I would still like to understand the logic behind this.

    1 Reply Last reply
    0
    • p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #2

      Hi,

      Did you initiliase mBaseFolder using new operator ?
      But why do you want to ? QString uses "implicit sharing":http://qt-project.org/doc/qt-5/qstring.html#details

      157

      1 Reply Last reply
      0
      • P Offline
        P Offline
        primem0ver
        wrote on last edited by
        #3

        well that seems odd considering what "fixed" the problem. Please see my "EDIT: FYI:" in the original post.

        1 Reply Last reply
        0
        • dheerendraD Offline
          dheerendraD Offline
          dheerendra
          Qt Champions 2022
          wrote on last edited by
          #4

          There is nothing assigned to mBaseFolder. It has invalid address. You need to change QString *mBaseFollder to QString mBaseFolder.

          Dheerendra
          @Community Service
          Certified Qt Specialist
          http://www.pthinks.com

          1 Reply Last reply
          0
          • P Offline
            P Offline
            primem0ver
            wrote on last edited by
            #5

            No... that is not true. mBaseFolder is a pointer that is assigned in the constructor. If you read my edit above it says "It might help to know that mBaseFolder is initialized with a QString allocated on the stack in the main executable..."

            and FYI: yes... I do convert from the QString to the pointer using the address operator.

            1 Reply Last reply
            0
            • T Offline
              T Offline
              topse
              wrote on last edited by
              #6

              Is your constructor like this:

              @
              {
              QString myString = "bla";
              mBaseFolder = &myString;
              }
              @

              ??

              1 Reply Last reply
              0
              • T Offline
                T Offline
                tilsitt
                wrote on last edited by
                #7

                Hi,

                It would help to see more of your code. Are you sure the QString you take the adress from to pass it to your A class is still alive when you use it?

                1 Reply Last reply
                0
                • P Offline
                  P Offline
                  primem0ver
                  wrote on last edited by
                  #8

                  Ok.... here you go (class names changed but this is essentially the code):

                  @
                  // from main()
                  ...
                  QString appPath(QApplication::applicationDirPath());
                  A aInstance(&appPath);
                  aInstance.assignBaseDir();
                  @

                  @
                  // A class initializer
                  A::A(QString* basePath) :
                  mBaseDir(NULL),
                  mBaseFolder(basePath)
                  {
                  }
                  @

                  Please keep in mind that A is in a dll while main is in the executable. Is it simply that the dll does not have access to the executable's stack space?

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Hi,

                    There's no need to allocate QStrings on the heap. Just use const references when passing it around, it will only get copied once you modify it.

                    @
                    {
                    QString myString = "bla";
                    mBaseFolder = &myString;
                    } <- myString is destroyed, mBaseFolder becomes a dangling pointer.
                    @

                    Look at p3c0's link, it explains everything nicely

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • T Offline
                      T Offline
                      topse
                      wrote on last edited by
                      #10

                      [quote]
                      @
                      // from main()
                      ...
                      QString appPath(QApplication::applicationDirPath());
                      A aInstance(&appPath);
                      aInstance.assignBaseDir();
                      @

                      [/quote]

                      In line 3 you create a QString-Object on Stack. You pass a pointer to that object to your other function. Somewhere after line "5" I assume there is a "}" which you did not show. When that "}" comes, your stack-objects, including the QString are getting destroyed. When you later access the QStrings pointer, the memory is no longer valid.

                      Sorry -- this is kind of a beginners mistake :-/ Just do it as said before -- in your class A you should use "QString" rather than "QString *".

                      Best Regards,
                      Tobias

                      1 Reply Last reply
                      0
                      • T Offline
                        T Offline
                        topse
                        wrote on last edited by
                        #11

                        [quote author="primem0ver" date="1410684255"]Ok.... here you go Is it simply that the dll does not have access to the executable's stack space?[/quote]

                        No one has access to each others stack space... Stack-Objects are destroyed when leaving context...

                        In General: dont use pointers to objects on stack!!

                        1 Reply Last reply
                        0
                        • P Offline
                          P Offline
                          primem0ver
                          wrote on last edited by
                          #12

                          [quote author="topse" date="1410696530"][quote]
                          @
                          // from main()
                          ...
                          QString appPath(QApplication::applicationDirPath());
                          A aInstance(&appPath);
                          aInstance.assignBaseDir();
                          @

                          [/quote]

                          In line 3 you create a QString-Object on Stack. You pass a pointer to that object to your other function. Somewhere after line "5" I assume there is a "}" which you did not show. When that "}" comes, your stack-objects, including the QString are getting destroyed. When you later access the QStrings pointer, the memory is no longer valid.

                          Sorry -- this is kind of a beginners mistake :-/ Just do it as said before -- in your class A you should use "QString" rather than "QString *".

                          Best Regards,
                          Tobias
                          [/quote]

                          Yes... I am aware that stack space is deallocated for temporary variables in braces when the braces are left. That isn't the issue because the code with the problem is not in a block inside the main method. Don't forget that the the stack space for the main method is not deallocated until the just before the program exits (because the closing brace is at the end of the program).

                          I think your second suggestion is the actual problem. Also SGaist's probably applies as well. Thanks!

                          Edit: Actually after reading through the implicit sharing for a deeper understanding of how it works and looking back at SGaists suggestion... if I am understanding the article correctly his suggestion isn't quite right either because as I said, the original object does not get destroyed until AFTER the main loop is exited... the '}'/closing brace containing the code isn't exited until then... am I missing something?

                          1 Reply Last reply
                          0
                          • P Offline
                            P Offline
                            primem0ver
                            wrote on last edited by
                            #13

                            Here is where I get confused (even after reading the article)

                            [quote author="SGaist" date="1410691278"]Hi,

                            There's no need to allocate QStrings on the heap. Just use const references when passing it around, it will only get copied once you modify it.

                            @
                            {
                            QString myString = "bla";
                            mBaseFolder = &myString;
                            } <- myString is destroyed, mBaseFolder becomes a dangling pointer.
                            @
                            [/quote]

                            what would happen if the above code was a function that actually returned myString? (And mBaseFolder was the variable that received it?) Would it still be destroyed? Why or why not? If it is destroyed then allocating QStrings on the heap IS necessary.

                            1 Reply Last reply
                            0
                            • T Offline
                              T Offline
                              topse
                              wrote on last edited by
                              #14

                              You really should make up your basics about memory management in C++. Or better: use JAVA, there you wont have those problems.

                              Again: myString is an Object on Stack. mBaseFolder stores an address to a memory area on stack. This memory area gets invalid in the moment of "}". Ergo: mBaseFolder points to an invalid address.

                              And yes: you should allocate any object on heap, if you want to store pointers. And yes: in Qt you normally dont need to use pointers.

                              Please just do what we said:

                              @
                              class A
                              {
                              private:
                              QString _myString;
                              public:
                              void setMyString(const QString &newValue)
                              {
                              _myString = newValue;
                              }
                              }
                              @

                              I really dont know how we can help more. My feeling your is, that your problem concern generally C++ and Memory Management. Its nothing Qt-specific.

                              Best Regards,
                              Tobias

                              1 Reply Last reply
                              0
                              • SGaistS Offline
                                SGaistS Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                [quote author="topse" date="1410710884"]
                                snip
                                And yes: you should allocate any object on heap, if you want to store pointers. And yes: in Qt you normally dont need to use pointers.
                                snip again
                                [/quote]

                                That last yes is not true, you don't need to allocate on the heap Qt's container classes, QString/QByteArray and some other classes (see the documentation for implicit sharing) but for the rest common C++ rules applies, even more for QObject derived class since you can't copy them.

                                Interested in AI ? www.idiap.ch
                                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                1 Reply Last reply
                                0

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved