CL.SHALLOW.COPY

由于复制构造函数中的浅层复制而释放已释放的内存

这是一个类级别 (CL) 检查器,可告知由于在复制构造函数中进行浅层复制导致类析构函数双重释放堆内存的潜在情况。如果一个类析构函数释放由一个或多个数据成员所指的动态内存(仅当在复制构造函数中对这些指针执行浅层复制时),Klocwork 将报告 CL.SHALLOW.COPY。

漏洞与风险

在执行浅层复制后,调用复制构造函数将导致具有数据成员的两个对象指向同一动态内存。如果没有恰当的引用计数设备,第一个对象超出范围时,类析构函数将释放两个对象之间共享的内存。第二个对象的相应数据成员将指向现已删除的内存位置。第二个对象超出范围时,其析构函数将尝试再次释放此内存。这可能导致应用程序崩溃和/或堆内存损坏。

漏洞代码示例 1

复制
    struct D {
        /* omitted for brevity */
    };

    class C {
    public
        C();
        ~C() {
            delete d;
       }
       C(const C& rhs) {
           d = rhs.d;    // shallow copy
       }
   private
       C& operator=(const C&);
       D* d;
   };

在此示例中,在复制构造函数中对成员指针 d 执行了浅层复制。相应堆内存释放于析构函数 ~C() 中。Klocwork 将这种潜在的危险情况标记为 CL.SHALLOW.COPY。

修正代码示例 1

复制
    struct D {
        /* omitted for brevity */
        D(const D&);
    };

    class C {
    public
        C();
        ~C() {
           delete d;
       }
       C(const C& rhs) {   
           d = new D(*rhs.d);
       }
   private
       C& operator=(const C&);
       D* d;
   }; 

在修正代码示例 1 中,在复制构造函数中执行了深层复制;因此,调用两个对象的析构函数时不会发生双重释放的情况。

安全培训

应用程序安全培训材料由 Secure Code Warrior 提供。

扩展

此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 C/C++ 分析。