分段错误strcpy

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

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

  • 你有语法错误:char *hallName = NULL, char *command = NULL;.

  • 你不检查strtok()的return值:它可以是NULL以防不匹配。

  • 你无缘无故传递指针的地址hallName,传递值而已

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

  • 您将 movie 定义为 struct Movie 的类型定义,但还使用 Movie 作为 createHall() 中局部变量的名称。这非常令人困惑。 struct 标签和 typedef 都使用 Movie,局部变量使用小写 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