加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 10:05:15 所属栏目:百科 来源:网络整理
导读:我有一个指向结构的指针向量,这些结构存储在我学校项目的另一个向量中.当我尝试使用指针更改结构中的元素时,由于某种原因导致未定义的行为.我删除了与下面问题相关的部分代码. #include vector#include string#include iostreamclass someException{};enum c
我有一个指向结构的指针向量,这些结构存储在我学校项目的另一个向量中.当我尝试使用指针更改结构中的元素时,由于某种原因导致未定义的行为.我删除了与下面问题相关的部分代码.

#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 << ",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: 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,Status: RUNNING
After creating process A
ReadyList results:
Process: ROOT,Status: RUNNING
Process: A,Priority: 1,Status: READY
Process: A,Status: RUNNING

ProcessList设置为正确的值,进程A正在运行并处理ROOT就绪,但由于某种原因,ReadyList保持不变.在我的原始代码中,读取列表中进程ROOT的PID字符串值变为空,并且在更改状态后,我在此示例中遗漏的进程中存储的映射值也被清除.
我还测试了直接使用readyList指针进行更改,而不是使用findRunningProcess函数返回的指针,它没有修复PID和映射值的问题,但在进程状态中导致了一些其他未定义的行为.我对可能导致此问题的想法不满意,请帮忙!非常感谢.

解决方法

每次你:

processList.push_back(process);

矢量可能会调整大小.这意味着支持向量的数据存储区将被复制到新的数据存储区中,然后被丢弃.这将为您提供另外两个向量,其中包含已释放并可能已重新分配的内存指针.

processList是一个使用std :: list或std :: deque的好地方,因为它们在增长时不会使指针无效. std :: deque应该具有一些性能优势,因为它往往具有更好的空间局部性.

另一种方法是让其他两个向量存储processList中的进程索引,因为只要你只回退并且不删除进程它们就不会改变.

在任何一种情况下,从processList中删除进程而不确保它们首先从其他向量中删除将是一个坏主意. std :: deque处于不利之处,如果你有erase a process from the middle,那么删除会使指针无效.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读