gpt4 book ai didi

C++ 修改指向结构的指针 vector 会导致未定义的行为

转载 作者:太空狗 更新时间:2023-10-29 20:10:07 26 4
gpt4 key购买 nike

我有一个指针 vector ,指向存储在我学校项目的另一个 vector 中的结构。当我尝试使用指针更改结构中的元素时,由于某种原因它导致了未定义的行为。我删除了与以下问题相关的部分代码。

#include <vector>
#include <string>
#include <iostream>

class someException{};

enum class ProcessStatus{
RUNNING,
READY
};

struct Process{
int priority;
std::string PID;
ProcessStatus status;
Process(){
status = ProcessStatus::READY;
}
};

struct ReadyList{
std::vector<Process*> priority1;
std::vector<Process*> priority0;
};

class ProcessManager{
private:
std::vector<Process> processList;
ReadyList readyList;
public:
ProcessManager(){};

void createProcess(std::string PID, int priority){
Process process;
process.priority = priority;
process.PID = PID;
if (priority == 0)
process.status = ProcessStatus::RUNNING;
processList.push_back(process);
switch(priority){
case 0:
readyList.priority0.push_back(&processList.at(processList.size()-1));
break;
case 1:
readyList.priority1.push_back(&processList.at(processList.size()-1));
break;
default:
throw someException();
}
schedule(findRunningProcess());
}

void printProcesses(){
std::cout<<"ReadyList results:"<<std::endl;
for(auto &process: readyList.priority0){
std::cout << "Process: "<< process->PID << " , Priority: "<<process->priority;
if (process->status == ProcessStatus::RUNNING)
std::cout << ", Status: RUNNING"<< std::endl;
else
std::cout <<", Status: READY"<<std::endl;
}
for(auto &process: readyList.priority1){
std::cout << "Process: "<< process->PID << " , Priority: "<<process->priority;
if (process->status == ProcessStatus::RUNNING)
std::cout << ", Status: RUNNING"<< std::endl;
else
std::cout <<", Status: READY"<<std::endl;
}
std::cout<<"ProcessList results: "<<std::endl;
for(auto &process: processList){
std::cout << "Process: "<< process.PID << " , Priority: "<<process.priority;
if (process.status == ProcessStatus::RUNNING)
std::cout << ", Status: RUNNING"<< std::endl;
else
std::cout <<", Status: READY"<<std::endl;
}
}

private:
void schedule(Process* currentProcess){
Process* highestPriorityProcess;
if (readyList.priority1.size()>0)
highestPriorityProcess = readyList.priority1[0];
else
highestPriorityProcess = readyList.priority0[0];
if (currentProcess->priority < highestPriorityProcess->priority){
currentProcess->status = ProcessStatus::READY;
highestPriorityProcess->status = ProcessStatus::RUNNING;
}
}

Process* findRunningProcess(){
for (auto &process: processList){
if (process.status == ProcessStatus::RUNNING){
return &process;
}
}
return nullptr;
}
};

int main(){
ProcessManager pm = ProcessManager();
pm.createProcess("ROOT", 0);
std::cout<<"After creating process ROOT"<<std::endl;
pm.printProcesses();
pm.createProcess("A", 1);
std::cout<<"After creating process A"<<std::endl;
pm.printProcesses();
return 0;
};

输出结果是这样的:

After creating process ROOT
ReadyList results:
Process: ROOT , Priority: 0, Status: RUNNING
ProcessList results:
Process: ROOT , Priority: 0, Status: RUNNING
After creating process A
ReadyList results:
Process: ROOT , Priority: 0, Status: RUNNING
Process: A , Priority: 1, Status: RUNNING
ProcessList results:
Process: ROOT , Priority: 0, Status: READY
Process: A , Priority: 1, Status: RUNNING

ProcessList 设置为正确的值,进程 A 正在运行并且进程 ROOT 就绪,但由于某种原因 ReadyList 未更改。在我的原始代码中,就绪列表中进程 ROOT 的 PID 字符串值变为空,并且我在本示例中遗漏的进程中存储的映射值在更改状态后也被清除。我还测试了直接使用 readyList 指针进行更改,而不是使用 findRunningProcess 函数返回的指针,这没有解决 PID 和映射值的问题,但在进程状态中导致了一些其他未定义的行为。我不知道是什么原因造成的,请帮忙!非常感谢。

最佳答案

每次你:

processList.push_back(process);

vector 可以调整大小。这意味着支持 vector 的数据存储将被复制到一个新的数据存储中,然后被丢弃。这给您留下了另外两个 vector,其中包含指向已释放并可能重新分配的内存的指针。

processList 是使用 std::liststd::deque 的好地方,因为它们不会使指针无效随着他们的成长。 std::deque 应该具有一些性能优势,因为它往往具有更好的空间局部性。

另一种方法是让另外两个 vector 将进程的索引存储在 processList 中,因为只要您只推回而不删除它们,它们就不会改变过程。

在任何一种情况下,从 processList 中删除进程而不确保它们首先从其他 vector 中删除将是一个坏主意。 std::deque 在删除时处于劣势 erase a process from the middle因为这会使指针无效。

关于C++ 修改指向结构的指针 vector 会导致未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41843625/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com