分段错误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。
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。