Menu

Potential FP: returnDanglingLifetime

2022-12-16
2022-12-17
  • Muhammad Javed

    Muhammad Javed - 2022-12-16

    I have a case where I believe cppcheck assesses that a pointer (that gets returned) points to an object that will be destructed upon function exit, which it does not. Here is the sample case:

    // test.cpp
    #include <memory>
    #include <vector>
    
    std::vector<std::unique_ptr<int>> intPtrs;
    
    int* storePtr(int num)
    {
        std::unique_ptr<int> localPtr(new int(num));
        int* ret = localPtr.get();
        intPtrs.push_back(std::move(localPtr));
        return ret; // cppcheck reports returnDanglingLifetime here
    }
    

    I run cppcheck on the file above and I get:

    Checking test.cpp ...
    test.cpp:12:12: error: Returning pointer to local variable 'localPtr' that will be invalid when returning. [returnDanglingLifetime]
        return ret;
               ^
    test.cpp:10:28: note: Raw pointer to smart pointer created here.
        int* ret = localPtr.get();
                               ^
    test.cpp:9:26: note: Variable created here.
        std::unique_ptr<int> localPtr(new int(num));
                             ^
    test.cpp:12:12: note: Returning pointer to local variable 'localPtr' that will be invalid when returning.
        return ret;
               ^
    

    Also, it's quite odd that the error says I'm pointing to a local variable when it's actually pointing to the heap-allocated int returned by localPtr.get().

    Out of curiosity, I created a behaviorally equivalent portion of code (confirmed by Compiler Explorer) that, oddly, does not reproduce the cppcheck error. This furthers my suspicion that this is a false positive. Here is the equivalent code that does not produce the same error:

    // equivalentCase.cpp
    #include <memory>
    #include <vector>
    
    std::vector<std::unique_ptr<int>> intPtrs;
    
    int* storePtr(int num)
    {
        auto localPtr = std::unique_ptr<int>(new int(num));
        int* ret = localPtr.get();
        intPtrs.push_back(std::move(localPtr));
        return ret; // no error here, or anywhere else
    }
    

    I only changed how I defined localPtr. I hope this information helps in some way.

    I understand the code is a little funky and that I could also use std::make_unique which would probably avoid the error. However, I am running into a case in my project where I am not using std::make_unique and I am instead constructing a std::unique_ptr from an existing pointer. Thanks!

     

    Last edit: Muhammad Javed 2022-12-16
  • CHR

    CHR - 2022-12-17

    Thanks for reporting, ticket is here: https://trac.cppcheck.net/ticket/11439

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.