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

C++内存重分配时指针引用的用法及相关编译错误求解

关于C++指针引用与动态内存重分配的问题

问题1:编译错误的原因是什么?

你遇到的编译错误invalid initialization of non-const reference of type 'char*&' from an rvalue of type 'char*',核心原因是数组退化为指针时产生的是右值,无法绑定到非常量左值引用:

  • 当你在main里调用Mystrcat(str0, ", World!")时,str0是栈上的char[100]数组,传递给函数参数时会自动退化为char*类型的临时右值(这个临时指针指向数组首地址,但本身是不可修改的临时值)。
  • 而函数参数char* &des是非常量左值引用,C++规定非常量左值引用只能绑定到可被修改的左值(比如明确的char*变量),不能绑定右值,因此编译报错。

你误以为char* &des = str0合法,但这句代码本身也会编译失败——str0是数组名,不是char*类型变量,数组名可隐式转换为char*右值,但同样无法绑定到非常量左值引用。

另外要注意:你试图通过修改des重新分配内存的逻辑,本身和栈数组不兼容。栈上数组的内存是编译期固定分配的,地址不可改变,即使编译通过,把des改成new出来的堆地址,也不会改变原栈数组str0的内存,反而会造成内存泄漏。

问题2:如何在内存重分配时使用指针引用?

指针引用的作用是让函数能修改传入的指针变量本身(比如改变指针指向的地址),但使用前提是:传入的必须是可修改的char*类型左值(即动态分配的指针变量),而非栈上的数组。

修正后的完整代码

#include <iostream>
#include <cstring>

// 实现自定义字符串长度函数
unsigned int Mystrlen(const char* str) {
    unsigned int len = 0;
    while (str[len] != '\0') {
        len++;
    }
    return len;
}

void Mystrcat(char* &des, const char* src) {
    unsigned int des_len = Mystrlen(des);
    unsigned int src_len = Mystrlen(src);
    
    char* temp_str = des;
    // 分配足够容纳拼接后字符串的新内存
    des = new char[des_len + src_len + 1]; 
    
    // 复制原字符串内容
    for(unsigned int i = 0; i < des_len; i++) {
        des[i] = temp_str[i];
    }
    // 拼接源字符串内容
    for(unsigned int i = 0; i < src_len; i++) {
        des[des_len + i] = src[i];
    }
    // 添加字符串结束符,避免乱码
    des[des_len + src_len] = '\0';
    
    // 释放原内存,防止泄漏
    delete[] temp_str;
}

int main() {
    // 使用动态分配的指针,替代栈数组
    char* str0 = new char[100];
    std::strcpy(str0, "Hello");
    
    Mystrcat(str0, ", World!"); 
    std::cout << str0 << std::endl; // 输出"Hello, World!"
    
    // 释放动态分配的内存
    delete[] str0;
    return 0;
}

关键要点说明:

  • 用动态指针替代栈数组:栈数组地址固定,无法通过指针引用修改指向;只有动态分配的char*变量,才能通过引用修改其指向,让它指向重新分配的堆内存。
  • 释放原内存:分配新内存后必须释放原temp_str指向的内存,避免内存泄漏。
  • 补充字符串结束符:原代码未添加'\0',会导致输出乱码,必须手动添加字符串结束标记。
  • 类型匹配:Mystrlen返回unsigned int,循环变量建议同步使用该类型,避免类型不匹配警告。

你之前提到用char* des作为参数时无法获取数组总大小——这是因为数组退化为指针后,sizeof(des)只能得到指针本身的大小(如4或8字节),无法获取原数组长度。如果要处理栈数组的拼接,需要额外传递数组总容量参数,但这种情况下无法修改数组内存(栈数组容量固定),只能在原有容量内完成拼接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:30:59