2012-07-09 246 views
0

我有這樣的結構:通過函數數組指針循環

typedef struct { 
    void (*func)(instruction); 
    union { 
     double db; 
     char ch; 
    }; 
} instruction; 

在我的源文件,我有這些說明的數組。我的問題是,我將如何遍歷該數組並執行每個結構的函數?

我以爲我知道如何做到這一點,但指令函數有一個參數是一個指令的事實似乎會導致問題。因此,這不起作用:

int i; 
    for (i = 0; i <= instr_count; i++) { 
     (*instr[i].func) (instr[i]); 
     } 

instr是指令數組。這是填充數組的函數。數組本身在文件的頂部聲明。

void read_instructions() 
{ 
    char* str; 
    char *instruct; 
    int n; 
    char c; 
    instruction next = {0}; 
    while (!feof(datafile)) { 
     // Fetch the next string 
     // if (push or pop), get the next argument 
     // create instructiwn and add to instruction array 
     str = get_next_string(); 

     instruct = strtok (str, " "); 

     if (strncmp (instruct, "P", 1) == 0) { 
      char *arg = strtok (NULL, " "); 
      if (strncmp (str, "PUSH", 4) == 0) { 
       next.func = pushFunc; 
      } 
      else { 
       next.func = popFunc; 
      } 
      n = arg[0]; 
      if (n > 64 || n < 71) 
       next.ch = n; 
      else { 
       double n; 
       scanf ("%lf", arg, n); 
       next.db = n; 
      } 
      instr[instr_count] = next; 
      instr_count++; 
     } 
     else { 
      c = instruct[0]; 


      switch (c) { 
      case 'A' : 
       next.func = addFunc; 
       break; 
      case 'S' : 
       next.func = subFunc; 
       break; 
      case 'M' : 
       next.func = multFunc; 
       break; 
      case 'D' : 
       next.func = divFunc; 
       break; 
      default : 
       break; 
      } 
      instr[instr_count] = next; 
      instr_count++; 
     } 
    } 
    fclose (datafile); 
} 

作爲快速解釋,這個代碼採取的「中間碼」的文件時,確定該指令,並且對於每個保持適當的函數指針創建的指令結構。

運行代碼給了我這個運行時錯誤:

"Unhandled exception at 0x00000000 in Interpreter.exe: 0xC0000005: Access violation." (Compiled using VS 2010).

+1

看起來你的函數指針之一是NULL指針。 – FatalError 2012-07-09 02:55:57

+0

這確實在哪一行中崩潰? – alk 2012-07-09 08:13:57

回答

0

這很難說,不看你的代碼的其餘部分,但在錯誤(0x00000000)中列出的地址,意味着你的函數指針之一在陣列中是NULL

您能否在通過它之前驗證您的數組是否已正確初始化?

+0

我已經編輯我的帖子,以包括假設填充數組的函數。 – Troncoso 2012-07-09 03:07:31

+0

@Troncoso考慮遇到'P','A','S','M'或'D'以外的情況。你的輸入是什麼樣的? – reuben 2012-07-09 03:09:53

+0

我的意見非常嚴格。說明只有Pop,Push,Add,Sub,Mult和Div。每條指令都在一條獨立的線上。因爲這是一個類的分配,它並不是要測試不正確的輸入。 – Troncoso 2012-07-09 03:15:04

1

根據instr是否爲instructioninstruction *一個數組,你想要麼

instr[i].func(&instr[i]); 

instr[i]->func(instr[i]); 

我懷疑你想第一個(的instruction陣列),因爲你有什麼將爲此編譯(對大多數編譯器有警告);你只會在函數中獲取參數的垃圾。

你得到的異常表明,這不是你的問題,但是 - 你可能有一個指令,在你的數組中有一個NULL func指針。

編輯

看起來你正在做的經典while(!feof(input))錯誤 - 當你看到這一點,它幾乎總是錯的。

問題在於,在讀取輸入的最後一行之後,feof仍然會返回false - 直到您嘗試讀取PAST輸入的末尾並接收到EOF結果時纔會返回true。因此,在輸入代碼結束後,您會得到一個循環的額外迭代,並且可能會導致您看到的崩潰。

你可能想要的是像while (!(str = get_next_string()))或許while (!(str = fgets(buffer, sizeof(buffer), datafile)))

+0

我已經編輯我的帖子,包括假設要填充數組的函數。 – Troncoso 2012-07-09 03:08:12