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

C++向函数传递类实例引发的问题及原理咨询

C++值传递引发的Buffer内存异常问题解析

先看你的Buffer类实现:

#pragma once

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

class Buffer
{
public:

  Buffer(uint16_t bytes)
  {
    ptr = malloc(size = bytes);
  }

  ~Buffer()
  {
    free(ptr);
  }

  inline char* str() { return (char*)ptr; }

  inline int length() { return strlen(str()); }

  void* ptr;
  uint16_t size;

};

针对你的问题逐一解答:

非引用参数的函数签名含义

writeSomething(Buffer buffer)这种签名表示:函数接收一个Buffer类型的参数副本,属于C++里的值传递方式。函数内部对这个buffer参数的修改不会影响到外部的原对象。

传递的是什么

当你调用writeSomething(text)时,编译器会自动创建一个text对象的浅拷贝副本——因为你的Buffer类没有自定义拷贝构造函数,编译器会生成默认的拷贝构造函数,把原对象的ptr和size成员直接复制给副本对象。这就导致副本的ptr和原对象text的ptr指向同一块堆内存。

为何析构函数会在此处触发

当writeSomething函数执行完毕时,函数内的局部变量(也就是那个Buffer副本buffer)会被销毁,此时会自动调用Buffer的析构函数~Buffer(),而析构函数里会调用free(ptr)释放这块共享的内存。

此时原对象text的ptr还指向已经被释放的内存,后续执行doSomethingElse(text.ptr)时,就会访问已经被释放的堆内存,触发内存异常。

而改成writeSomething(Buffer& buffer)(引用参数)后,函数接收的是原对象text的引用,不会创建副本,函数结束后也不会有局部对象销毁,自然不会触发析构函数释放内存,原对象的ptr依然有效,问题就解决了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:10:29