C++桌面任务通知应用开发:vector添加元素后数据访问异常问题求助
Hey there, let's break down what's causing those weird display glitches and crashes in your task app, then fix it up properly!
What's Going Wrong?
Your current code has a critical memory management issue, plus a small typo that's making things worse:
- You're using
std::vector<LPWSTR>to store task names and content, but LPWSTR is just a pointer to a wide character array—not the actual string content. - The
Text_nameandText_contentvariables are local arrays inside the button click event. When the event function finishes running, these local variables are destroyed, and the memory they occupied gets freed or reused. - Every time you call
push_back(Text_name), you're storing the same pointer in the vector. So all elements inNameTaskandContentTaskpoint to the same piece of memory. By the time you go to display the first element, that memory has been overwritten with the last task you entered. Worse, accessing that memory later (like with your "view task" button) leads to a wild pointer, causing crashes or garbage output. - You also had a typo:
ContentTask.push_back(Text_name);should be pushingText_content, not the name again!
The Fix: Use std::wstring Instead of Raw Pointers
C++'s std::wstring handles memory management automatically, storing the actual string content instead of just a pointer. This eliminates the wild pointer problem entirely.
Step 1: Update Your Vector Declarations
Replace your pointer vectors with std::wstring vectors:
// Old (problematic): // std::vector <LPWSTR> NameTask; // std::vector <LPWSTR> ContentTask; // New (safe): std::vector<std::wstring> NameTask; std::vector<std::wstring> ContentTask;
Step 2: Rewrite the Button Click Logic
Update the event handler to use std::wstring and fix the typo:
if (wmId == ID_BUTTON) { int len_name = GetWindowTextLength(TextBox_Name) + 1; int len_content = GetWindowTextLength(TextBox_content) + 1; // Use std::wstring to safely store the input text (no fixed size limits!) std::wstring Text_name(len_name, L'\0'); std::wstring Text_content(len_content, L'\0'); // Pull text from the edit boxes into our strings GetWindowText(TextBox_Name, Text_name.data(), len_name); GetWindowText(TextBox_content, Text_content.data(), len_content); // Validate input if (Text_name.empty() || Text_content.empty()) { MessageBox(hWnd, L"Name and content can't be empty", L"Error", MB_OK); } else { // Push copies of the actual string content into the vectors NameTask.push_back(Text_name); ContentTask.push_back(Text_content); // Fixed the typo here! // Display the first task's name (use c_str() to get a Win32-compatible pointer) SetWindowText(TextBox_content, NameTask[0].c_str()); // Optional: Clear input boxes for better user experience SetWindowText(TextBox_Name, L""); SetWindowText(TextBox_content, L""); } }
Step 3: Fix the "View Task" Button
When you want to display a task's name or content later, just use the c_str() method to get a const wchar_t* (fully compatible with Win32 API functions like SetWindowText):
// Example: Display the i-th task's content in an output box if (!ContentTask.empty() && i < ContentTask.size()) { SetWindowText(YourOutputTextBox, ContentTask[i].c_str()); }
Why This Works
std::wstringcreates a copy of the input text when you push it into the vector, so each element in the vector has its own independent copy of the string.- The string's memory is managed automatically—you don't have to worry about freeing it or dealing with invalid pointers after local variables go out of scope.
内容的提问来源于stack exchange,提问作者MrEngineer

