Segfault与std :: list用法 [英] Segfault with std::list usage

查看:210
本文介绍了Segfault与std :: list用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java用户来到C ++,我很难理解这个语句出了什么问题。我的程序已经segfault在任何地方我放置 push_back 命令。所以我想知道究竟是怎么回事。

I'm Java user coming over to C++, and I am having a hard time understanding what is going wrong with this statement. My program has been segfaulting anywhere I put the push_back command. So I'm wondering what exactly is going on.

class Process {
  public:
    int nice;
    int arrivalTime;
    int cpuBursts;
    list<int> burstList;

    Process() {
      burstList.push_back(10); // Segfaults here...
   }  
}; 

以下是完整代码:

#include<iostream>
#include<stdlib.h>
#include<fstream>
#include<list>
#include<string.h>

using namespace std;

int calcTimeslice(int priority);
int calcOriginalPrio(int nice);
int readFile(int ,char **);
int calcPrioBonus(int,int);
void tokenizeAndAdd(char *);

class Bursts {
  public:
    int isCPUBurst;
    int time;

    Bursts() {}
    // Constructor to make it easier to add to list
    Bursts(int tempIsCPU, int tempTime) {
      isCPUBurst = tempIsCPU;
      time = tempTime;
    }

};

class Process {
  public:
    int nice;
    int arrivalTime;
    int cpuBursts;
    list<int> burstList;

    Process() {
      burstList.push_back(10);
   }
};



int main(int arg, char **argv) {

  // This is if the file was not correctly read into the program
  // or it doesnt exist ...
  if(readFile(arg,argv)==-1) {
    cout << "File could not be read. \n";
    return -1;
  }
  //cout << "Original Calc Whatever: " << calcOriginal(19) << '\n';
  return 0;

}

/*
 *  Calculates the timeslice based on the priority
 */
int calcTimeslice(int priority) {
  double finalCalc;

  // This is the given function in the prompt
  finalCalc = ( (1 - (priority / 140)) * 290 + (.5) ) + 10;

  // Cast to int, this will be a truncate
  return ((int)finalCalc);
}

int readFile(int arg, char **argv) { 
  char *temp,*pointer;
  int endOfFile = 1;

  // While its not the end of the file
  while(endOfFile) {
    // Read in the input from stdin
    fgets(temp,256,stdin);

    // Check to see if this line had a * in it
    if(*temp =='*')
      endOfFile = 0;
    else
      tokenizeAndAdd(temp);
  }

  return 0; 

}

void tokenizeAndAdd(char *string) {
  char *token = strtok(string," \n"); 
  int i = 0;
  Process p;

  while(token != NULL) {
    cout << token << endl;
    if(i>2) {  // If it is odd (CPU burst)
      if(i%2 == 1) {
        int tempInt = atoi(token);
        //p.burstList.push_back(tempInt); 
      }
      else { // If it is even (IO burst)
        int tempInt = atoi(token);
        //p.burstLis.push_back(tempInt); 
      }      
    }
    else if(i==0)
      p.nice = atoi(token);
    else if(i==1)
      p.arrivalTime = atoi(token);
    else if(i==2)
      p.cpuBursts = atoi(token);

    token = strtok(NULL," \n");
    i++;
  }

  //cout << p.nice << " " << p.arrivalTime << " " << p.cpuBursts << "\n";
  //i = 0;
  //cout << p.burstList.size() << "\n";
  //  cout << 
  //}
  return;
}

/*
 *  Calculates and returns the original priority based on the nice number
 *    provided in the file.
 */
int calcOriginalPrio(int nice) {
  double finalCalc;

  // This is the given function from the prompt
  finalCalc = (( nice + 20 ) / 39 ) * 30 + 105.5;

  // Cast to int, this is a truncate in C++
  return ((int)finalCalc);
}

/* 
 * Calculates the bonus time given to a process
 */
int calcPrioBonus(int totalCPU, int totalIO) {
  double finalCalc;

  // How to calculate bonus off of the prompt
  if(totalCPU < totalIO)
    finalCalc = ( (1 - (totalCPU / (double)totalIO)) * (-5)) - .5;
  else
    finalCalc = ( (1 - (totalIO / (double)totalCPU)) * 5) + .5;

  // Cast to int
  return ((int)finalCalc);
}


推荐答案

您正在使用 temp 在以下代码中未初始化:

You are using temp uninitialized in the following code:

char *temp;
...
while(endOfFile) {
  fgets(temp,256,stdin);
  ...

这可以有任何副作用,因为它很可能会毁坏你的堆栈或堆内存的部分。它可能会立即失败(当调用 fgets()函数),它可能失败以后(如你的示例)或甚至可以运行正常 - 可能直到你升级操作系统,你的编译器或任何东西,或直到你想在另一台机器上运行相同的可执行文件。这是未定义的行为

This can have any side effect, since it most likely destroys your stack or parts of the heap memory. It could fail immediately (when calling the fgets() function), it could fail later (as in your sample) or it could even run fine - maybe until you upgrade your OS, your compiler or anything else, or until you want to run the same executable on another machine. This is called undefined behaviour.

您需要为 temp 变量分配空间,不是指针。使用类似

You need to allocate space for the temp variable, not a pointer only. Use something like

char temp[256];
...
while(endOfFile) {
  fgets(temp,256,stdin);
  ...

有关详细信息,请参阅 fgets() 文档。第一个参数是一个指向char数组的指针,即 fgets()将存储已读取的字节。在你的代码中,你传递一个未初始化的指针,这意味着 fgets()将存储字节到一个未定义的内存位置 - 这是由操作系统终止你的应用程序与分段错误。

For more information, see the fgets() documentation. The first parameter is a pointer to a char array - that is where fgets() will store the bytes which have been read. In your code, you pass an uninitialized pointer which means that fgets() will store the bytes to an undefined memory location - this is catched by the OS which terminates your application with a segmentation fault.

BTW:编译时应该考虑启用pedantic警告 - 我用

BTW: You should consider enabling pedantic warnings when compiling - I compiled with

g++ -Wall -pedantic -o list list.cpp

它给了我以下警告:

list.cpp: In function 'int readFile(int, char**)':
list.cpp:76:26: warning: 'temp' may be used uninitialized in this function [-Wuninitialized]

这篇关于Segfault与std :: list用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆