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. Out of scope pointer - how to fix?
Forum Updated to NodeBB v4.3 + New Features

Out of scope pointer - how to fix?

Scheduled Pinned Locked Moved General and Desktop
16 Posts 4 Posters 4.2k 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.
  • K Offline
    K Offline
    koahnig
    wrote on last edited by
    #2

    You need to give more details about your code for proper answering, but it looks like you are using a temporary object for instance like in:
    @
    void foo ()
    {
    {
    wchar_t lpBuffer[MAX_PATH] = {0};
    wchar_t *pch = lpBuffer;

         // pointer should be valid in here 
      }
    

    // pointer is no longer valid
    }
    @
    You need to allocate memory with new.

    BTW it has nothing to do with Qt

    Vote the answer(s) that helped you to solve your issue(s)

    1 Reply Last reply
    0
    • S Offline
      S Offline
      syfy323
      wrote on last edited by
      #3

      @void TaskHdd::getLocalDisks()
      {
      DWORD nBufferLength = MAX_PATH;
      wchar_t lpBuffer[MAX_PATH] = {0};

      DWORD dwResult = GetLogicalDriveStrings(nBufferLength,lpBuffer);
      
      if (dwResult > 0 && dwResult <= MAX_PATH)
      {
          wchar_t *pch = lpBuffer;
      
          while (*pch) {
              // Type 3 = fixed drive
              if(GetDriveType(pch) == 3)
              {
                  HddAllocation *hdd = new HddAllocation(pch);
                  hardDiskAllocationList.append(hdd);
              }
      
              // jump to next drive
              pch = &pch[wcslen(pch) + 1];
          }
      
      }else{
          //TODO: Log - no local HDDs found.
      }
      

      }@

      "HddAllocation(pch);": In my constructor I copy the pointer to pointer, I know this can't work as soon as the constructor is left (return).

      @HddAllocation::HddAllocation(const wchar_t *mountPoint, QObject *parent ) :
      QObject(parent)
      {
      lpDirectoryName = mountPoint;
      lpFreeBytesAvailable = new ULARGE_INTEGER;
      lpTotalNumberOfBytes = new ULARGE_INTEGER;
      lpTotalNumberOfFreeBytes = new ULARGE_INTEGER;

      //get initial values
      refreshValues();
      

      }@

      I want to change my code - my constrcutor should get a static wchar_t which is written into my "wchar_t *hddName;".

      As the object behind lpBuffer is just temp, the current behavior is "working as expected". I just don't know how to copy the const inside my constrcutor.

      1 Reply Last reply
      0
      • C Offline
        C Offline
        code_fodder
        wrote on last edited by
        #4

        What do you mean by "I just don’t know how to copy the const inside my constrcutor"?

        Do you mean to say you want to copy the data pointed to by const wchar_t *mountPoint? (i.e. you want to store that "string"?)

        Or you just want to copy the pointer value itself?

        1 Reply Last reply
        0
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by
          #5

          This will do it:
          @
          auto len = wcslen(mountPoint);
          lpDirectoryName = new wchar_t[len+1];
          lpDirectoryName[len] = 0;
          memcpy(lpDirectoryName, mountPoint, len * sizeof(wchar_t));
          @

          But seriously I would suggest you use QString and don't fiddle with "new" and raw pointers so much.

          1 Reply Last reply
          0
          • S Offline
            S Offline
            syfy323
            wrote on last edited by
            #6

            [quote author="Chris Kawa" date="1393861342"]
            @
            auto len = wcslen(mountPoint);
            lpDirectoryName = new wchar_t[len+1];
            lpDirectoryName[len] = 0;
            memcpy(lpDirectoryName, mountPoint, len * sizeof(wchar_t));
            @
            [/quote]

            Perfect! This is what I searched for the whole day ;-)

            You are true, I would like to avoid MS VC++ and Qt mix but Win32API (which I am implementing in my app) needs pointer wchar_t's. I would like to use Qt classed instead.

            Thanks for your help, I did not know that I need to specify the array length, I just allocated via "new wchar_t" and memcpy'ed the content (this also explains why this was not working, as it was the wrong length).

            1 Reply Last reply
            0
            • Chris KawaC Offline
              Chris KawaC Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by
              #7

              Yeah, it works, but I would still recommend something like:
              @
              QStringList logicalDrives()
              {
              auto length = GetLogicalDriveStrings(0, nullptr);
              auto array = std::make_unique<wchar_t[]>(length + 1);
              GetLogicalDriveStrings(length + 1, array.get());
              return QString::fromWCharArray(array.get(), length)
              .split(QChar('\0'), QString::SkipEmptyParts);
              }
              @

              No "new"s, don't have to worry about freeing stuff, no memcpy (yuck) etc.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                syfy323
                wrote on last edited by
                #8

                And how do I cast QString to wchar_t?

                @BOOL WINAPI GetDiskFreeSpaceEx(
                In_opt LPCTSTR lpDirectoryName,
                Out_opt PULARGE_INTEGER lpFreeBytesAvailable,
                Out_opt PULARGE_INTEGER lpTotalNumberOfBytes,
                Out_opt PULARGE_INTEGER lpTotalNumberOfFreeBytes
                );@

                1 Reply Last reply
                0
                • Chris KawaC Offline
                  Chris KawaC Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on last edited by
                  #9

                  Eg.
                  @
                  QString s = "whatever";
                  WhateverWinAPICall(s.toStdWString().c_str());
                  @

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    syfy323
                    wrote on last edited by
                    #10

                    Thanks, I will try this.
                    Slowly I get into this.

                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      koahnig
                      wrote on last edited by
                      #11

                      You like to copy lpBuffer (the pointer) or the content it points to?

                      At the moment you are copying the pointer only and keep.
                      This like making a scratch in the paint of a boat where someone was falling off. In harbor you can tell the rescue guys exactly where the guy felt off. Unfortunately, it will not rescue the guy from drowning ;- )

                      In the constructor you would need to allocate memory and copy from one pointer to the other.

                      @
                      lpDirectoryName = new wchar_t [MAX_PATH];
                      memcpy (lpDirectoryName, mountPoint, sizeof (wchar_t) * MAX_PATH);
                      @
                      Please check with size. This is not tested.

                      Alternatively, you can copy byte by byte in a for loop.

                      Personally I would copy the information to string. std::string or QString. The followup handling is easier.

                      [edit, since interrupted, I had missed out the other exchange, koahnig]

                      Vote the answer(s) that helped you to solve your issue(s)

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        syfy323
                        wrote on last edited by
                        #12

                        [quote author="Chris Kawa" date="1393862155"]Yeah, it works, but I would still recommend something like:
                        @
                        QStringList logicalDrives()
                        {
                        auto length = GetLogicalDriveStrings(0, nullptr);
                        auto array = std::make_unique<wchar_t[]>(length + 1);
                        GetLogicalDriveStrings(length + 1, array.get());
                        return QString::fromWCharArray(array.get(), length)
                        .split(QChar('\0'), QString::SkipEmptyParts);
                        }
                        @

                        No "new"s, don't have to worry about freeing stuff, no memcpy (yuck) etc.[/quote]

                        How can I do the same without C++11? Auto and nullptr are undefined and even std::make_unique throws "is not a member" when C++11 is enabled.

                        Thanks.

                        1 Reply Last reply
                        0
                        • Chris KawaC Offline
                          Chris KawaC Offline
                          Chris Kawa
                          Lifetime Qt Champion
                          wrote on last edited by
                          #13

                          Yeah, sorry, make_unique is actually part of C++14 but newer compilers already support it for some time so I'm used to it (I can't recommend enough to upgrade. It's another world :) ).

                          In C++03 just replace the nice stuff with the ugly one :)
                          @
                          QStringList logicalDrives()
                          {
                          DWORD length = GetLogicalDriveStrings(0, NULL);
                          QScopedPointer<wchar_t, QScopedPointerArrayDeleter<wchar_t> > array(new wchar_t[length+1]);
                          GetLogicalDriveStrings(length + 1, array.data());
                          return QString::fromWCharArray(array.data(), length)
                          .split(QChar('\0'), QString::SkipEmptyParts);
                          }
                          @

                          1 Reply Last reply
                          0
                          • S Offline
                            S Offline
                            syfy323
                            wrote on last edited by
                            #14

                            Do I have any new dependencies for my application? I am using Qt 5.2.1, most likly I upgrade to any new release. If there are no new dependencies, I would upgrade, too.

                            1 Reply Last reply
                            0
                            • Chris KawaC Offline
                              Chris KawaC Offline
                              Chris Kawa
                              Lifetime Qt Champion
                              wrote on last edited by
                              #15

                              Well it depends on what you're using now :)
                              For MSVC make_unique is available from VS2013 (or VS2012 November CTP to be precise) and if you're using MinGW 4.8 from the online installer it's already there, you just need to add QMAKE_CXXFLAGS += -std=c++1y in the .pro file.

                              As for app dependencies - only the usual: Qt libs, plugins, and system/compiler runtime just like in any version.

                              1 Reply Last reply
                              0
                              • S Offline
                                S Offline
                                syfy323
                                wrote on last edited by
                                #16

                                -I still get this warning:-
                                @C:\folder\file.cpp:53: Warnung: 'auto' changes meaning in C++11; please remove it [-Wc++0x-compat]@

                                -as well as:-
                                @C:\folder\file.cpp:53: Fehler: 'length' does not name a type
                                auto length = GetLogicalDriveStrings(0, nullptr);
                                ^@

                                -I tried the online MinGW install, but there are components missing / headers are not compatible anymore in several of my classes.-

                                Works now, just had to comment out my WINVER define.
                                Now I am not able to compile some spcial Vista+ APIs but I can solve this later.

                                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