流水线/超标量性能代码分段故障

时间:2014-12-17 19:53:51

标签: c architecture segmentation-fault pipeline

我正在研究C中的这个代码,它计算并绘制了6级管道式和超标量架构的总周期数。 代码编译很好,但是当我运行它时,我得到一个分段错误。

我在此选项中遇到分段错误。我输入我的选择为1,然后输入总周期为5.此外,用户应输入指令,例如 r0 = r1 + r2但我不确定如何提示

 void EnterInst(){
   char instr_string[9];
   int i;
   printf("Enter total number of instructions: ");
   scanf("%d\n", n);

  set = (instr*) malloc ((n+1) * sizeof(instr)); 
  set[0].dest = -1;

  for(i = 1; i <= n; i++){
  printf("%d", i);
  scanf("%s", instr_string);
  set[i].dest = instr_string[1]-'0';
  set[i].src1 = instr_string[4]-'0';
  set[i].src2 = instr_string[7]-'0';
 }
}  

当我选择2作为我的选择时,我也会遇到另一个分段错误。后面的代码是第二个选项

void pipelined(){
int overlap = 0;
int delay =0;

set[1].delay = 0;

int i;
for(i = 2; i <= n; i++){
  if((set[i-2].dest == set[i].src1) || (set[i-2].dest == set[i].src2)){
     if(overlap == 0){
        delay = 1;
        overlap = 1;
     }
     else{
        delay = 0;
        overlap = 0;
     }
  }//if RAW dep.
  else{ overlap = 0; }

  if((set[i-1].dest == set[i].src1) || (set[i-1].dest == set[i].src2)){
     delay = 2;
     overlap = 1;
  }
  set[i].delay = delay + 1 + set[i-1].delay;
 }//end for-loop
 //calculate total delay
 total_delay = set[n].delay;
 printf("Total number of cycles: %d", total_delay);
 printf("%d",print_Chart());
}

我真的很想知道为什么会发生分段错误以及如何解决它。这真让我烦恼。任何帮助是极大的赞赏。

1 个答案:

答案 0 :(得分:0)

suggest showing definition of 'n' and 'instr'
as that would greatly help with the debugging.

this line: char instr_string[9];
only has room for 8 characters plus the string terminator
however, the example input is 12 characters plus the string terminator
this is undefined behaviour and probably is 
the root cause of the seg fault event in the EnterInst() function


set[i].dest = instr_string[1]-'0'; <-- gets 0x30 - 0x30 so set[i].dest = 0
set[i].src1 = instr_string[4]-'0'; <-- gets 0x20 - 0x30 so set[i].src1 = -16
set[i].src2 = instr_string[7]-'0'; <-- gets 0x20 - 0x30 so set[i].src2 = -16

that is probably not what you want.

however, scanf stops on any white space (like a space and newline), so this line:

scanf("%s", instr_string);

will fail to input anything beyond the "r0"

therefore, the next calls, in the loop, to scanf will get nothing.

The above is a very good reason to always check the returned code from any 
input function and to use a leading ' ' in scanf format strings

suggest using fgets to input a whole line into a buffer
then parse the data from that buffer 

for several reasons, the returned value from the malloc family
should not be cast
I.E. 
set = (instr*) malloc ((n+1) * sizeof(instr));
should be:
set = malloc ((n+1) * sizeof(instr));
and the returned value should be checked, I.E.
if( NULL == (set = malloc ((n+1) * sizeof(instr)) )
{
    perror( "malloc failed" );
    exit( EXIT_FAILURE );
}

the code might prompt as follows for the instruction:
int regValue = -1;
do
{
    printf( "input destination register number (0...9):" )
    if( 1 != scanf( " %d", &regValue ) )
    {  // then, scanf failed
        perror( "scanf failed for destination register number" );
        exit(EXIT_FAILURE);
    }
while( (0 <= regValue) && (9 >= regValue) );
set[0].dest = regValue;

with similar statements for the other registers, and the operator

the variable 'set' is a action verb, probably good as the first part of 
a function name, but does not give a good representation
of a variable name, especially as it yields no indication
of its' contents.

in C, array references begin with 0 and end with 1 less than the array size
so to avoid skipping the first 'instr' entry in the 'set' array of structs
use:

for(i = 0; i < n; i++){ rather than: for(i = 1; i <= n; i++){