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

二维动态数组扩展失败:调用expand函数后抛出异常

问题分析与修复

你的代码抛出异常主要有两个核心问题,还有一个输入处理的小问题,逐一说明:

核心问题1:新扩展的数组元素未初始化

expand函数中,新分配的temparr只复制了原数组中已有的noofelements个元素,从noofelements到新rows-1的位置都是未初始化的野指针。当调用expand后,你立刻尝试用cin.getline写入arr[noofelements](也就是新数组中未初始化的位置),这会访问非法内存,直接触发异常。

核心问题2:rows参数未按引用传递

expand函数中的rows是按值传递的,函数内对rows的修改不会同步到main函数的rows变量。这会导致main里的条件判断noofelements < rows永远用旧的rows值(初始5),逻辑彻底混乱——比如第一次扩展后noofelements变成5,rows还是5,会再次进入else分支重复调用expand,加剧野指针问题。

输入处理小问题:cin缓冲区残留换行符

用户输入字符串后按下回车,换行符会留在输入缓冲区,下一次cin.getline会直接读取这个换行符作为空字符串,导致noofelements错误递增,可能提前触发扩展逻辑。


修复后的代码

#include<iostream>
#include<limits> // 用于numeric_limits
using namespace std;

// rows改为引用传递,同步更新main中的rows值
void expand(char**& arr, int& rows, int noofelements)
{
    int newRows = rows + 5;
    char** temparr = new char*[newRows];
    // 复制原有元素
    for (int i = 0; i < noofelements; i++)
    {
        temparr[i] = arr[i];
    }
    // 初始化新扩展的元素,分配内存
    for (int i = noofelements; i < newRows; i++)
    {
        temparr[i] = new char[50];
    }
    delete[] arr;
    arr = temparr;
    rows = newRows; // 更新rows的值
    cout << "******\narray was expanded\n*****\n";
}

int main()
{
    char** arr;
    int rows = 5, noofelements = 0;
    arr = new char*[rows];
    for (int i = 0; i < rows; i++)
    {
        arr[i] = new char[50];
    }
    while (1)
    {
        if (noofelements < rows)
        {
            cout << "enter string\n";
            // 先忽略缓冲区中的换行符,避免读取空字符串
            if (noofelements > 0)
            {
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
            }
            cin.getline(arr[noofelements++], 50);
        }
        else
        {
            expand(arr, rows, noofelements);
            cout << "enter string\n";
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cin.getline(arr[noofelements++], 50);
        }
    }
    // 实际使用中需在退出循环时释放内存,避免泄漏
    for (int i = 0; i < rows; i++)
    {
        delete[] arr[i];
    }
    delete[] arr;
    return 0;
}

关键修复点说明

  • rows改为引用传递:void expand(char**& arr, int& rows, int noofelements),确保函数内对rows的修改同步到main函数。
  • 初始化新扩展的元素:在expand中新增循环,为新分配的数组位置逐一分配char数组内存,避免野指针。
  • 处理输入缓冲区:使用cin.ignore清除输入缓冲区中的残留换行符,确保每次getline都能正确读取用户输入的字符串。
  • 添加内存释放逻辑:虽然是死循环,但实际代码中应该在退出时释放所有动态分配的内存,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:37:53