You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++类成员指针指向局部变量引发值异常问题求助

问题排查与修复

问题现象

创建Screen对象并初始化Diagonal的length成员后,首次直接访问screen->diagonal->length输出162,但调用get_length()方法后,length值变为32759,后续访问也保持异常值,预期三次输出均为162。尝试改写get_length()方法(使用指针等方式),问题仍未解决。

相关代码

Screen.h

#include "Diagonal/Diagonal.h"

class Screen {
public:
    Screen(const unsigned short _height) { // Constructor for diagonal initializing
        Diagonal diagonal{_height};
        this->diagonal = &diagonal;
    }

    Diagonal* diagonal{}; // Diagonal declaration

private:

};

Diagonal.h

struct Diagonal {
public:
    Diagonal() = default; // Default constructor

    Diagonal(const unsigned short _length) // Length initializing constructor
        : length{ _length } {}

    unsigned short get_length() const { // Get value of length
        return length;
    }

    const unsigned short length; // Screen length
private:

};

Main.cpp

#include <iostream>
#include "../Core/Headers/Screen/Screen.h"
#include <windows.h>

int main() {
    system("mode con cols=80 lines=162"); // Setting up the terminal's cols and lines
    MoveWindow(GetConsoleWindow(), 0, 0, 1400, 1000, true); // Setting up the terminal position when starts

    Screen* screen = new Screen{162};
    
    std::cout << screen->diagonal->length << std::endl;
    std::cout << screen->diagonal->get_length() << std::endl;
    std::cout << screen->diagonal->length << std::endl;

    delete screen;
}

问题根源

Screen构造函数中创建的Diagonal diagonal{_height}是局部变量,当构造函数执行完毕后,该局部变量会被销毁,其占用的内存会被系统回收或重新分配。此时screen->diagonal保存的是一个指向已销毁对象的指针(野指针),后续对该指针的访问属于未定义行为——第一次输出162只是巧合(内存还没被覆盖),调用get_length()后内存被改写,就出现了异常值。

修复方案

有两种常见的修复方式:

方案1:将Diagonal作为Screen的成员对象(推荐)

不需要使用指针,直接把Diagonal作为Screen的成员,彻底避免野指针问题:

// Screen.h 修改后
#include "Diagonal/Diagonal.h"

class Screen {
public:
    Screen(const unsigned short _height) : diagonal{_height} {}

    Diagonal diagonal; // 改为成员对象,而非指针

private:

};

Main.cpp中的访问方式对应调整:

std::cout << screen->diagonal.length << std::endl;
std::cout << screen->diagonal.get_length() << std::endl;
std::cout << screen->diagonal.length << std::endl;

方案2:动态分配Diagonal对象

如果必须使用指针,可以通过new动态分配内存,确保对象在Screen生命周期内有效:

// Screen.h 修改后
#include "Diagonal/Diagonal.h"

class Screen {
public:
    Screen(const unsigned short _height) {
        this->diagonal = new Diagonal{_height};
    }

    // 添加析构函数释放动态内存,避免内存泄漏
    ~Screen() {
        delete diagonal;
    }

    Diagonal* diagonal{};

private:
    // 禁用拷贝构造和赋值运算符,避免浅拷贝导致的重复释放问题
    Screen(const Screen&) = delete;
    Screen& operator=(const Screen&) = delete;
};

两种方案修改后,三次输出都会是预期的162,且不会出现未定义行为。

内容的提问来源于stack exchange,提问作者fzyier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 05:30:50