在其他函数中使用realloc后无法访问数组数据的问题求助
问题分析与修复方案
核心问题
你的代码存在两个关键问题导致内存访问异常:
- 指针传递方式错误:
add_element函数接收的是指针的副本,realloc修改的只是函数内部的指针值,不会同步到main函数中的原始指针。这导致main里的students指针始终指向旧的内存地址(可能已被realloc释放)。 - C/C++内存管理混用:用
malloc/realloc分配包含std::string的结构体是不安全的——这些C函数不会调用C++对象的构造/析构函数,会导致字符串成员未初始化或资源泄漏;同时用delete[]释放malloc分配的内存属于未定义行为。
修复步骤
1. 修改指针传递方式
将add_element的第一个参数改为指针的引用,确保函数内对指针的修改能同步到main:
void add_element(student* &tab, int &size)
2. 替换为C++安全的内存管理
放弃malloc/realloc,改用new[]和delete[]来处理结构体数组,确保每个student对象的构造函数被正确调用。
3. 简化元素添加逻辑
不需要临时用new创建student对象,直接在新数组中初始化元素即可。
完整修复代码
#include <iostream> #include <string> #include <unistd.h> using namespace std; struct student { string name, last_name, date_of_birth; unsigned int index; char gender; }; void add_element(student* &tab, int &size) { int new_size = size + 1; // 分配新数组,自动调用student的构造函数 student* new_tab = new student[new_size]; // 复制原有元素 for (int i = 0; i < size; ++i) { new_tab[i] = tab[i]; } // 释放旧数组(如果存在) delete[] tab; tab = new_tab; // 直接初始化新元素 cout << "set name: "; cin >> tab[size].name; cout << "set last name: "; cin >> tab[size].last_name; cout << "set date of birth: "; cin >> tab[size].date_of_birth; cout << "set gender: "; cin >> tab[size].gender; cout << "set index: "; cin >> tab[size].index; size = new_size; cout << tab->name << endl; // 此处可正常访问 } void display(student tab[], int *size) { for (int i = 0; i < *size; i++) cout << (tab + i)->name << ' ' << (tab + i)->last_name << ", " << (tab + i)->date_of_birth << ", " << (tab + i)->gender << ", " << (tab + i)->index << endl; } void display(student tab[], int *size, int i) { if (i >= 0 && i < *size) { // 增加边界检查 cout << (tab + i)->name << ' ' << (tab + i)->last_name << ", " << (tab + i)->date_of_birth << ", " << (tab + i)->gender << ", " << (tab + i)->index << endl; } else { cout << "Invalid index!" << endl; } } int main() { int size = 0; student* students = nullptr; // 初始化为空指针 int option; do { cout << "\x1B[2J\x1B[H"; cout << "choose what to do\n"; cout << "0 - add element\n1 - display all elements\n2 - display specific element\n3 - exit\n"; cin >> option; switch (option) { case 0: add_element(students, size); cout << students->name << endl; // 现在可正常访问 sleep(2); break; case 1: display(students, &size); sleep(2); break; case 2: cout << "provide index for element to display\n"; int n; cin >> n; display(students, &size, n); sleep(2); break; case 3: break; default: cout << "option doesn't exist\n"; sleep(2); } } while (option != 3); delete[] students; // 安全释放内存 return 0; }
额外说明
- 新增了索引有效性检查,避免越界访问
- 初始化为空指针,避免
delete[]释放未分配的内存 - 完全遵循C++内存管理规则,确保所有对象的生命周期被正确处理
内容的提问来源于stack exchange,提问作者User temporary
相关产品推荐
相关产品推荐

