[英]Why segmentation fault after altering pointer to struct?
我目前有功能代码,当我尝试将 function 排除在文件到数组的转换之外时,我遇到了分段错误。 我知道fileToArray
内部的对象是正确的(就myData
对象而言),因为在 function 内部时, myData.length
和myData.array
都正确返回。 但是,在 main 中引用了指针后,出现了段错误。 我是 c 的新手,但是如果没有指向结构的特定指针,所有这些都可以正常工作。
因此,如果我使用带有多行文本的文件的参数调用该程序,则会发生设置错误。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
typedef struct {
int length;
char** array;
} FileStruct;
void fileToArray(FileStruct* fileDataPtr, int argc, char *argv[]){
int fd, i, n, count;
struct stat statbuf;
char *buf, *inbuf, *str, *saveptr;
char **array;
if ((fd = open(argv[1], O_RDONLY)) == -1) {
printf("Error opening file %s\n", argv[1]);
exit (-1);
}
if (lstat(argv[1], &statbuf) < 0) {
printf("Unable to lstat file %s\n", argv[1]);
exit (-1);
}
off_t filesize = statbuf.st_size;
buf = malloc(sizeof(char)*filesize);
array = malloc(sizeof(char *)*filesize);
count = 0;
if ((n = read(fd, buf, filesize)) > 0){
inbuf = buf;
for (i = 1; ; inbuf = NULL, i++) {
str = strtok_r(inbuf, "\n", &saveptr);
if (str == NULL)
break;
array[count] = malloc(sizeof(char)*(strlen(str)+1));
strcpy(array[count++], str);
}
} else {
printf("Error reading input file\n");
exit (-1);
}
close(fd);
// I know array works because it prints correctly here.
for (i = 0; i < count; i++) {
printf("%s\n", array[i]);
free(array[i]);
}
fileDataPtr->length = count;
fileDataPtr->array = array;
free(array);
free(buf);
}
int main(int argc, char *argv[]) {
int i;
FileStruct myData;
FileStruct* fileDataPtr = &myData;
fileToArray(fileDataPtr, argc, argv);
printf("length: %i", myData.length);
// I know this doesn't work because anything related to myData causes Seg fault.
// for (i = 0; i < 1; i++) {
// printf("%s\n", myData.array[i]);
// free(myData.array[i]);
// }
return 0;
}
在接近fileToArray
的末尾,将array
分配给fileDataPtr->array
,然后在下一行释放array
。 这将使fileDataPtr->array
指向已释放的 memory(一个悬空指针)。 当您稍后取消引用它时,您会陷入未定义的行为,并且任何事情都可能发生。
由于分配将分配的 memory 的所有权转移到fileDataPtr
,因此您不需要在从fileToArray
返回之前释放array
。
删除free(array);
线。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.