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

C++指针数组中引用无数据问题排查与修正求助

C++中BufferPool修改Page数据后无法正确输出的问题修复

问题核心原因

你的代码存在几个关键问题导致输出不符合预期:

  • 对象实例不统一:NewPage函数创建了堆上独立的Page对象,仅将其数据复制到BufferPool的pages数组对象中,返回的是堆对象指针。后续你修改的是堆上的实例,而非pages数组里的副本,因此FetchPage读取的是未被修改的旧数据。
  • 代码拼写错误:Page类的operator=重载里,std: memcpy少了一个冒号,应为std::memcpy,这会导致内存拷贝逻辑失效。
  • 构造函数初始化不完整:带参数的Page(int p_id)未初始化pin_count和data,存在未定义行为风险。
  • 字符数组无终止符:data是长度为10的数组,复制10个字符后没有\0终止符,直接用cout输出char*会出现异常。

修正后的完整代码

#include <iostream>
#include <cstring>

class Page
{
private:
    int page_id;
    int pin_count;
    char data[10]; // 保持要求的字符数组长度

public:
    Page()
    {
        page_id = 0;
        pin_count = 0;
        std::memset(data, 0, sizeof(data)); // 初始化data为空
    }

    Page(int p_id)
    {
        page_id = p_id;
        pin_count = 0; // 初始化pin_count
        std::memset(data, 0, sizeof(data)); // 初始化data
    }

    void IncPin()
    {
        pin_count += 1;
    }

    char* GetData()
    {
        return data;
    }

    // 重载常规的对象引用赋值运算符(更符合C++惯例)
    Page& operator=(const Page& p)
    {
        if (this == &p) return *this; // 防止自赋值
        page_id = p.page_id;
        pin_count = p.pin_count;
        std::memcpy(data, p.data, sizeof(data));
        return *this;
    }

    // 保留指针版本的赋值运算符(如果业务需要)
    void operator=(Page* p)
    {
        if (!p) return;
        page_id = p->page_id;
        pin_count = p->pin_count;
        std::memcpy(data, p->data, sizeof(data));
    }

    ~Page() {}
};

class BufferPool
{
private:
    Page* pages;
public:
    BufferPool()
    {
        pages = new Page[2];
    }

    Page* NewPage(int index)
    {
        // 直接操作pages数组内的对象,不再创建独立堆对象
        pages[index] = Page(1);
        pages[index].IncPin();
        // 返回数组中对象的指针,确保后续修改的是同一个实例
        return &pages[index];
    }

    void FetchPage(int index)
    {
        // 用cout.write输出固定长度字符,无需依赖\0终止符
        std::cout.write(pages[index].GetData(), sizeof(pages[index].GetData())) << std::endl;
    }

    // 添加析构函数释放内存,避免泄漏
    ~BufferPool()
    {
        delete[] pages;
    }
};

int main()
{
    BufferPool buffer_pool;
    Page* page = buffer_pool.NewPage(0);
    std::memcpy(page->GetData(), "aebclkfhti", 10);
    buffer_pool.FetchPage(0);
}

关键修改说明

  • 统一操作实例:NewPage直接修改pages数组内的Page对象,返回该对象的指针,确保后续修改的是BufferPool中存储的目标实例。
  • 修复拷贝逻辑:修正std: memcpy的拼写错误,保证内存拷贝正常执行。
  • 完善初始化:所有构造函数都初始化pin_count和data,消除未定义行为。
  • 安全输出数组:使用std::cout.write输出固定长度字符,不需要依赖\0终止符,适配10长度的字符数组要求。
  • 添加内存释放:给BufferPool增加析构函数,释放pages数组的内存,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:20:32