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

使用结构体的动态内存分配问题:搜索学号时程序崩溃

问题分析与修复方案

嘿,我帮你找出程序崩溃的原因啦,主要是指针操作和循环逻辑出了问题,咱们一步步拆解:

1. 导致崩溃的核心问题:错误移动了动态数组的起始指针

在输入数据的循环里,你写了p++;——这会让指针p每次循环都向后偏移一个data结构体的大小。等输入循环结束后,p已经完全脱离了最开始用new data[i]分配的数组起始地址!

后面你用p[j]访问元素时,本质是从数组末尾之外的非法内存区域开始读取,直接触发了内存访问错误,导致程序崩溃。而且最后执行delete[] p时,因为p不再是数组的起始指针,也会触发未定义行为。

2. 搜索循环的双重错误

  • 循环条件写错:for (int j = 0; i < i; j++)里的i < i永远是false,这个循环根本不会执行(应该是你笔误写成了i < i,正确的条件是j < i)。但就算改了条件,因为p已经偏移了,还是会访问非法内存。
  • 搜索逻辑错误:如果第一个元素不匹配就直接break输出“Not found”,这会导致你只检查第一个元素就停止,完全没遍历所有输入的数据。

修复后的完整代码

#include <iostream>
using namespace std;

struct data { 
    char name[50]; 
    int roll; 
    float cgpa; 
    char camp[3]; 
}; 

int main() { 
    data *p; 
    int i; 
    cout << "how many times you want to enter data? "; 
    cin >> i; 
    p = new data[i]; 

    // 输入数据:用数组下标访问,不要移动原始指针p
    for (int k = 0; k < i; k++) { 
        cout << "Enter your name: "; 
        cin >> p[k].name; 
        cout << "Enter your roll number: "; 
        cin >> p[k].roll; 
        cout << "Enter your CGPA: "; 
        cin >> p[k].cgpa; 
        cout << "Enter your camp (max 2 characters): "; 
        cin >> p[k].camp; 
        cout << endl << endl;
        // 删掉这里的p++!
    } 

    int r; 
    cout << "enter roll number to search for: "; 
    cin >> r; 

    bool found = false;
    // 遍历所有元素,用原始指针p(指向数组开头),条件为j < i
    for (int j = 0; j < i; j++){ 
        if (p[j].roll == r) { 
            cout << "Roll number: " << p[j].roll << endl; 
            cout << "Name: " << p[j].name << endl; 
            cout << "CGPA: " << p[j].cgpa << endl; 
            cout << "Camp: " << p[j].camp << endl; 
            found = true;
            break; // 找到后提前退出循环
        } 
    } 

    // 所有元素遍历完都没找到才输出提示
    if (!found) {
        cout << "Not found!" << endl;
    }

    delete []p; // 现在p还是数组起始指针,delete操作合法
    return 0; 
}

额外的小建议

  • 永远不要修改动态分配数组的起始指针,如果需要移动指针,可以用临时变量,比如data* temp = p;,然后操作temp++,这样原始的p还能保留起始地址。
  • camp是char camp[3],最多只能存2个字符加结束符\0,记得提醒用户输入不要超过2个字符,避免缓冲区溢出。
  • 推荐用C++的std::string代替字符数组,既安全又不用手动管理缓冲区大小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:05:07