C++动态扩容通讯录程序触发Write Access Violation错误求助
Let's break down exactly what's causing your error and fix it, along with some small tweaks to make your code more reliable.
The Core Issue: Passing Pointers by Value Instead of Reference
Your growArray function is the main source of the Write Access Violation. Right now, you're passing the contacts pointer by value to the function. That means when you update contacts = new_array inside growArray, you're only modifying a local copy of the pointer—not the original pointer in your main function.
Here's the play-by-play of the bug:
- In
main,contactspoints to an array of 1Contact. - When
ireachescurrentLength, you callgrowArray(currentLength, contacts). - Inside
growArray, you allocate a new larger array, copy the old elements, thendelete[] contacts(this frees the original array frommain). - You set the local
contactspointer to the new array, but this change never makes it back tomain. - Back in
main, the originalcontactspointer still points to already freed memory. The next time you try to accesscontacts[i], you're touching invalid memory, which triggers the violation.
Fix for growArray
Change the function parameter to pass the pointer by reference (Contact* &contacts) so modifications inside the function affect the original pointer in main:
void growArray(int ¤tLength, Contact* &contacts) { int multiplier = 2; Contact *new_array = new Contact[currentLength * multiplier]; for (int i = 0; i < currentLength; i++) { new_array[i] = contacts[i]; } delete[] contacts; contacts = new_array; currentLength *= multiplier; }
Other Quick Improvements to Avoid Future Bugs
1. Rename the exit Member Variable
exit is a reserved keyword in C++ (it refers to the std::exit function). Using it as a struct member can lead to weird, hard-to-debug behavior. Rename it to something like exitChoice:
struct Contact { string name; string number; string address; string exitChoice; // Renamed from 'exit' };
Update references to it in userPrompt and main too:
// In userPrompt cout << "Exit? (y/n): "; getline(cin, contact.exitChoice); // In main's loop if (contacts[i].exitChoice == "y" or contacts[i].exitChoice == "Y") { break; }
2. Clean Up Allocated Memory
You're dynamically allocating the contacts array, so don't forget to free it at the end of main to avoid memory leaks:
// At the end of main, after showAllContacts delete[] contacts;
Full Fixed Code
Here's the complete corrected version with all changes applied:
#include "pch.h" #include <iostream> #include <string> using namespace std; struct Contact { string name; string number; string address; string exitChoice; // Renamed from 'exit' }; void userPrompt(Contact &contact) { cout << "Name: "; getline(cin, contact.name); cout << "Phone number: "; getline(cin, contact.number); cout << "Address: "; getline(cin, contact.address); cout << "Exit? (y/n): "; getline(cin, contact.exitChoice); } void printContact(Contact &contact) { cout << "Name: " << contact.name << endl; cout << "Phone number: " << contact.number << endl; cout << "Address: " << contact.address << "\n" << endl; } void growArray(int ¤tLength, Contact* &contacts) { int multiplier = 2; Contact *new_array = new Contact[currentLength * multiplier]; for (int i = 0; i < currentLength; i++) { new_array[i] = contacts[i]; } delete[] contacts; contacts = new_array; currentLength *= multiplier; } void showAllContacts(Contact *contacts, int length) { for (int i = 0; i < length; i++) { if (contacts[i].name.length() != 0) { printContact(contacts[i]); } } } int main() { Contact *contacts = new Contact[1]; int currentLength = 1; int i = 0; while (true) { userPrompt(contacts[i]); if (contacts[i].exitChoice == "y" or contacts[i].exitChoice == "Y") { break; } i++; if (i == currentLength) { growArray(currentLength, contacts); } } showAllContacts(contacts, currentLength); delete[] contacts; // Clean up memory }
内容的提问来源于stack exchange,提问作者Abusayeed Roni

