使用结构体的动态内存分配问题:搜索学号时程序崩溃
问题分析与修复方案
嘿,我帮你找出程序崩溃的原因啦,主要是指针操作和循环逻辑出了问题,咱们一步步拆解:
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
相关产品推荐
相关产品推荐

