分段故障strcpy

时间:2016-10-30 12:04:51

标签: c segmentation-fault strcpy

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

我动态创建了电影数组。在processCommand函数中:

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
    ...
}

1 个答案:

答案 0 :(得分:1)

您的代码中存在多个问题:

  • 您遇到语法错误:char *hallName = NULL, char *command = NULL;

  • 您不会检查strtok()的返回值:如果不匹配,可以是NULL

  • 您无缘无故地传递指针hallName的地址,只需传递该值。

  • 您没有检查潜在的溢出:如果hallName指向长字符串,strcpy()将导致缓冲区溢出。

  • 您将movie定义为struct Movie的typedef,但也使用Movie作为createHall()中本地变量的名称。这非常令人困惑。对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():它的语义通常被误解并且非常容易出错。见布鲁斯道森的this article