2016-10-30 67 views
0
typedef struct Movie{ 
    char hallName[50]; 
    char movieName[50]; 
}movie; 

我已動態創建的影片陣列。在processCommand功能:段錯誤strcpy的

char *hallName; 
hallName = strtok(NULL," "); 

,並呼籲createHall功能與此參數。

createHall(&halllName); 

然後在createHall函數我在這裏創建了電影結構元素並賦值。我想hallName複製到Movie.hallName。我這樣做strcpy,但我在Linux中得到一個分段錯誤。在Windows中,此代碼正常工作。

strcpy(Movie.hallName, *hallName); 

我該如何解決這個問題?

編輯:

int main(int argc, char *argv[]) 
{ 
    FILE *inputFile = fopen(argv[1], "r+"); 
    FILE *outputFile = fopen("output.txt","w+"); 
    char *line=NULL; 
    movie *Movies = (movie*)malloc((hallNumber)*sizeof(movie)); 

    while(1) { 
      line = readLine(inputFile); 
      if (line == NULL) 
       break; 
      processCommand(line,outputFile,Movies,hallNumber); 
    } 
    free(Movies); 
    closeFiles(inputFile,outputFile); 
    return 1; 
} 

void processCommand(char *line) { 

    char *hallName = NULL, *command = NULL; 
    command = strtok(line, " "); 

    if (strcmp(command, "CREATEHALL") == 0) { 
      hallName = strtok(NULL, " "); 
      createHall(&hallName); 
    } 
    ... 
} 

void createHall(char **hallName) { 
    movie Movie; 
    strcpy(Movie.hallName, *hallName); // problem in here 
    ... 
} 
+5

你的代碼沒有上下文。 'hallName = strtok(NULL,「」);'孤立無用。請發佈顯示問題的[Minimal,Complete和Verifiable示例](http://stackoverflow.com/help/mcve)。 –

+0

那麼,爲什麼你驚訝地發現運行生成指針警告的代碼崩潰? –

+0

你不看strtok的回報,他可能是NULL。 'command = strtok(line,「」);'here too'hallName = strtok(NULL,「」);'爲什麼在createHall中發送一個'int **'。 – Stargateur

回答

1

有你的代碼中的多個問題:

  • 你有一個語法錯誤:char *hallName = NULL, char *command = NULL;

  • 你不檢查的strtok()返回值:它可以在NULL不匹配的情況。

  • 您無緣無故地傳遞指針hallName的地址,只需傳遞該值即可。

  • 您不檢查潛在溢出:如果hallName指向一個長字符串,strcpy()將導致緩衝區溢出。

  • 定義moviestruct Movie一個typedef而且在createHall()使用Movie的名稱爲您的局部變量。這很混亂。使用Movie同時爲struct標籤和局部變量typedef和小寫movie

下面是如何解決這些問題:

#include <stdio.h> 
#include <string.h> 

typedef struct Movie { 
    char hallName[50]; 
    char movieName[50]; 
} Movie; 

... 

void createHall(char *hallName) { 
    Movie movie; 
    snprintf(movie.hallName, sizeof movie.hallName, "%s", hallName); 
    ... 
    // do something with movie 
} 

void processCommand(char *line) { 

    char *hallName = NULL; 
    char *command = NULL; 

    command = strtok(line, " "); 

    if (command && strcmp(command, "CREATEHALL") == 0) { 
     hallName = strtok(NULL, " "); 
     if (hallName) { 
      createHall(hallName); 
     } 
    } 
} 

注意processCommand改性陣列它接收一個指針。這是一個糟糕的API。你應該儘量避免這種副作用。 strtok()正在引起這種副作用,並且由於它使用內部狀態而存在其他問題:避免使用此功能。


您最初在你的問題標題簡稱strncpy,我編輯了這一點,因爲你沒有實際使用它。事實上,你不應該使用strncpy():它的語義通常被誤解,很容易出錯。參見Bruce Dawson的this article

+0

你確定'movie.hallName'不是'char *'嗎?爲什麼不用strlen代替sizeof? – Stargateur

+0

你在哪裏看到'strncpy'? – t0mm13b

+0

@ t0mm13b看看[snprintf](https://linux.die.net/man/3/snprintf)。非常強大的功能。 – Stargateur