C - 分段错误(核心已转储),从文件中读取前 N 个字节
C - Segmentation fault (core dumped), read first N bytes from file
我写了一些代码来从二进制文件中读取前 pos
个字节并将其写入另一个文件。原来我在 运行 时遇到了分段错误。这是代码:
void outputUntillPos(const char * inFileName, const char * outFileName, int pos) {
FILE * inFile = fopen(inFileName, "r");
FILE * outFile = fopen(outFileName, "aw");
char buf[1024];
int read = 0;
int remain = pos;
do {
if(remain <= 1024) {
read = fread(buf, 1, pos, inFile);
} else {
read = fread(buf, 1, 1024, inFile);
}
remain -= read;
fwrite(buf, 1, read, outFile);
memset(buf, 0, 1024);
} while(remain > 0);
}
我这里有没有-运行ge 操作?
编辑:感谢大家的帮助,这里是编辑后的代码。
void outputUntillPos(const char * inFileName, const char * outFileName, int pos) {
FILE * inFile = fopen(inFileName, "r");
FILE * outFile = fopen(outFileName, "aw");
char buf[1024];
int read = 0;
int remain = pos;
if((inFile != NULL) && (outFile != NULL)) {
do {
if(remain <= 1024) {
read = fread(buf, 1, remain, inFile);
} else {
read = fread(buf, 1, 1024, inFile);
}
remain -= read;
fwrite(buf, 1, read, outFile);
memset(buf, 0, 1024);
} while(remain > 0 && read > 0);
}
fclose(inFile);
fclose(outFile);
}
当 remain
变为 <= 1024 并且输入块的 if
部分时,您正在读取 pos
字节,如果大于 1024 将写入过去缓冲区的结尾。这就是导致段错误的原因。
您想在此处使用 remain
:
if(remain <= 1024) {
read = fread(buf, 1, remain, inFile);
} else {
read = fread(buf, 1, 1024, inFile);
}
此外,请务必检查 fopen
的 return 值,并在 return.[=18= 之前检查 fclose(inFile)
和 fclose(outFile)
]
当要读取的剩余字节数(在变量 remain
中)小于 1024
时,您出于某种原因尝试读取 pos
字节。为什么 pos
???您应该在最后一次迭代中读取 remain
字节,而不是 pos
字节。
如果 pos
大于 1024
并且输入文件仍有额外数据,那么您当然会在最后一次迭代时溢出缓冲区。
我写了一些代码来从二进制文件中读取前 pos
个字节并将其写入另一个文件。原来我在 运行 时遇到了分段错误。这是代码:
void outputUntillPos(const char * inFileName, const char * outFileName, int pos) {
FILE * inFile = fopen(inFileName, "r");
FILE * outFile = fopen(outFileName, "aw");
char buf[1024];
int read = 0;
int remain = pos;
do {
if(remain <= 1024) {
read = fread(buf, 1, pos, inFile);
} else {
read = fread(buf, 1, 1024, inFile);
}
remain -= read;
fwrite(buf, 1, read, outFile);
memset(buf, 0, 1024);
} while(remain > 0);
}
我这里有没有-运行ge 操作?
编辑:感谢大家的帮助,这里是编辑后的代码。
void outputUntillPos(const char * inFileName, const char * outFileName, int pos) {
FILE * inFile = fopen(inFileName, "r");
FILE * outFile = fopen(outFileName, "aw");
char buf[1024];
int read = 0;
int remain = pos;
if((inFile != NULL) && (outFile != NULL)) {
do {
if(remain <= 1024) {
read = fread(buf, 1, remain, inFile);
} else {
read = fread(buf, 1, 1024, inFile);
}
remain -= read;
fwrite(buf, 1, read, outFile);
memset(buf, 0, 1024);
} while(remain > 0 && read > 0);
}
fclose(inFile);
fclose(outFile);
}
当 remain
变为 <= 1024 并且输入块的 if
部分时,您正在读取 pos
字节,如果大于 1024 将写入过去缓冲区的结尾。这就是导致段错误的原因。
您想在此处使用 remain
:
if(remain <= 1024) {
read = fread(buf, 1, remain, inFile);
} else {
read = fread(buf, 1, 1024, inFile);
}
此外,请务必检查 fopen
的 return 值,并在 return.[=18= 之前检查 fclose(inFile)
和 fclose(outFile)
]
当要读取的剩余字节数(在变量 remain
中)小于 1024
时,您出于某种原因尝试读取 pos
字节。为什么 pos
???您应该在最后一次迭代中读取 remain
字节,而不是 pos
字节。
如果 pos
大于 1024
并且输入文件仍有额外数据,那么您当然会在最后一次迭代时溢出缓冲区。