如何正确返回结构体指针数组并在main函数中正常访问?
问题分析与解决方案
你的代码存在几个核心问题导致崩溃和内存泄漏,以下是具体问题和修复方案:
核心问题
- 指针作用域错误:case 1中声明的
arr是局部变量,离开case块后就会失效,main后续代码无法访问该指针指向的内存。 - 未初始化指针访问:
dataPasien* arr = arr;这行代码完全无效,相当于用未定义的垃圾值给自己赋值,访问必然触发崩溃。 - 内存泄漏:input函数中用
new[]分配的数组没有对应的delete[],程序结束后内存无法释放。 - 输入逻辑问题:
cin.ignore()的时机不对,会导致getline读取空字符串,干扰正常输入流程。
推荐解决方案:使用std::vector(最安全便捷)
用std::vector替代手动分配的数组,它会自动管理内存,无需担心泄漏,同时天然支持动态扩容和安全访问。
修改后的完整代码
#include <iostream> #include <vector> #include <string> struct dataPasien { int id; int umur; std::string nama; std::string penyakit; }; void daftarMenu() { std::cout << "1. Input Data Pasien" << std::endl; std::cout << "2. Lihat Data" << std::endl; std::cout << "3. Edit Data" << std::endl; std::cout << "4. Keluar" << std::endl; } std::vector<dataPasien> input() { std::vector<dataPasien> arr; int jumlah; std::cout << "berapa pasien? "; std::cin >> jumlah; std::cin.ignore(); // 清除输入jumlah后的换行符,避免getline读取空行 arr.reserve(jumlah); // 预分配空间提升效率 for(int i = 0; i < jumlah; i++) { dataPasien pasien; pasien.id = i + 1; std::cout << "nama? "; getline(std::cin, pasien.nama); std::cout << "umur? "; std::cin >> pasien.umur; std::cin.ignore(); // 清除输入umur后的换行符 std::cout << "penyakit? "; getline(std::cin, pasien.penyakit); arr.push_back(pasien); } return arr; } int main() { int menu = 0; std::vector<dataPasien> pasienList; // 声明在main开头,全局作用域可用 std::cout << "Pilih menu: "; std::cin >> menu; std::cin.ignore(); // 清除输入menu后的换行符 switch(menu) { case 1: pasienList = input(); break; case 2: std::cout << "Menampilkan Data Pasien:" << std::endl; for(const auto& pasien : pasienList) { std::cout << "id : " << pasien.id << std::endl; std::cout << "nama : " << pasien.nama << std::endl; std::cout << "umur : " << pasien.umur << std::endl; std::cout << "penyakit : " << pasien.penyakit << std::endl; std::cout << "-------------------------" << std::endl; } break; case 3: // 可添加数据编辑逻辑 break; case 4: std::cout << "Keluar program." << std::endl; return 0; default: std::cout << "Menu tidak valid." << std::endl; break; } // 在switch外部也能正常访问数据 if(!pasienList.empty()) { std::cout << "\nData Pasien (di luar switch):" << std::endl; for(const auto& pasien : pasienList) { std::cout << "id : " << pasien.id << std::endl; std::cout << "nama : " << pasien.nama << std::endl; std::cout << "umur : " << pasien.umur << std::endl; std::cout << "penyakit : " << pasien.penyakit << std::endl; } } return 0; }
备选方案:使用智能指针管理数组
如果一定要用指针,使用std::unique_ptr<T[]>专门管理数组,它会在生命周期结束时自动调用delete[]释放内存,避免泄漏。
关键修改部分
#include <memory> // 引入智能指针头文件 // input函数返回智能指针,同时通过引用返回患者数量 std::unique_ptr<dataPasien[]> input(int& jumlah) { std::cout << "berapa pasien? "; std::cin >> jumlah; std::cin.ignore(); std::unique_ptr<dataPasien[]> arr(new dataPasien[jumlah]); // 按实际数量分配内存 for(int i = 0; i < jumlah; i++) { arr[i].id = i + 1; std::cout << "nama? "; getline(std::cin, arr[i].nama); std::cout << "umur? "; std::cin >> arr[i].umur; std::cin.ignore(); std::cout << "penyakit? "; getline(std::cin, arr[i].penyakit); } return arr; } int main() { int menu = 0; std::unique_ptr<dataPasien[]> arr; int jumlahPasien = 0; std::cout << "Pilih menu: "; std::cin >> menu; switch(menu) { case 1: arr = input(jumlahPasien); break; case 2: std::cout << "Menampilkan Data Pasien:" << std::endl; for(int i = 0; i < jumlahPasien; i++) { std::cout << "id : " << arr[i].id << std::endl; std::cout << "nama : " << arr[i].nama << std::endl; std::cout << "umur : " << arr[i].umur << std::endl; std::cout << "penyakit : " << arr[i].penyakit << std::endl; std::cout << "-------------------------" << std::endl; } break; // 其他case逻辑... } return 0; }
内容的提问来源于stack exchange,提问作者Ayodya Enhanayoan
相关产品推荐
相关产品推荐

