C 复制程序适用于小文件,在较大文件上出现分段错误
为了学习一些低级C魔法,我尝试实现不同的方法将一个文件的内容复制到另一个文件 下面的方法使用一个缓冲区,我在其中保存数据块,例如512字节。然后我从这个缓冲区写入目标文件。据称,这比直接复制整个文件更有效 当我使用一个小的缓冲区(例如512字节)时,这个效果很好。 如果我使用一个大的缓冲区,例如10000000字节,大约10MB,我会得到一个分段错误 我正在Ubuntu上运行。 我试过和malloc合作,但没有什么真正适合我的。一旦我知道了,我想解决问题会很容易 根据我的debbuger,错误在这行:C 复制程序适用于小文件,在较大文件上出现分段错误,c,C,为了学习一些低级C魔法,我尝试实现不同的方法将一个文件的内容复制到另一个文件 下面的方法使用一个缓冲区,我在其中保存数据块,例如512字节。然后我从这个缓冲区写入目标文件。据称,这比直接复制整个文件更有效 当我使用一个小的缓冲区(例如512字节)时,这个效果很好。 如果我使用一个大的缓冲区,例如10000000字节,大约10MB,我会得到一个分段错误 我正在Ubuntu上运行。 我试过和malloc合作,但没有什么真正适合我的。一旦我知道了,我想解决问题会很容易 根据我的debbuger,错误在
if (stat(to, &statBuffer) == -1)
我留下了很多我正在做的错误检查。
以下是我运行的代码:
void copyUsingBuffer(char from[], char to[], long unsigned int bufferSize)
{
struct stat statBuffer;
int sourceFD, destFD;
char buffer[bufferSize / sizeof(char)];
int EndOfFileErreicht = 0;
// Dateien pruefen
if (stat(to, &statBuffer) == -1)
{
if (errno != ENOENT)
{
perror("Fehler beim Pruefen der Zieldatei");
exit(EXIT_FAILURE);
}
}
else
{
if (!(S_ISREG(statBuffer.st_mode)))
{
printf("Die Zieldatei ist keine regulaere Datei\n");
exit(EXIT_FAILURE);
}
}
// Dateien oeffnen
sourceFD = open(from, O_RDONLY);
if (sourceFD == -1)
{
perror("Fehler beim Oeffnen der Quelldatei");
exit(EXIT_FAILURE);
}
if (fstat(sourceFD, &statBuffer) == -1)
{
perror("Fehler beim Pruefen der Quelldatei");
exit(EXIT_FAILURE);
}
if (!(S_ISREG(statBuffer.st_mode)))
{
printf("Die Quelldatei ist keine regulaere Datei\n");
exit(EXIT_FAILURE);
}
destFD = open(to, O_WRONLY | O_CREAT | O_TRUNC, statBuffer.st_mode);
if (destFD == -1)
{
perror("Fehler beim Oeffnen der Zieldatei");
exit(EXIT_FAILURE);
}
while (EndOfFileErreicht == 0)
{
int geleseneBytes = read(sourceFD, buffer, sizeof(buffer));
if (geleseneBytes == -1)
{
perror("Fehler beim Lesen aus der Quelldatei");
exit(EXIT_FAILURE);
}
if (geleseneBytes < bufferSize)
{
// EOF wurde erreicht, also Flag setzen
EndOfFileErreicht = 1;
}
if (write(destFD, buffer, geleseneBytes) == -1)
{
perror("Fehler beim Schreiben in die Zieldatei");
exit(EXIT_FAILURE);
}
}
close(sourceFD);
close(destFD);
}
但是,当我使用这个文件将被破坏
如果有人有更好的解决方案,例如malloc,这也将是一个很大的帮助
备选案文1:
不要将bufferSize作为函数的输入。使用您知道将要使用的硬编码尺寸
不会导致缓冲区溢出,例如
备选案文2:
使用std::vector代替数组
// char buffer[bufferSize / sizeof(char)];
std::vector<char> buffer(bufferSize);
在尝试了一些事情之后,找到了解决方案。 我代替
char buffer[bufferSize / sizeof(char)];
与
已经有人建议使用malloc。我的错误是没有替换
int geleseneBytes = read(sourceFD, buffer, sizeof(buffer));
我的程序可以对所有文件大小进行更改。
谢谢大家的帮助
int geleseneBytes = read(sourceFD, buffer, bufferSize);
您还需要更改行:
int geleseneBytes = read(sourceFD, buffer, sizeof(buffer));
To:
int geleseneBytes = read(sourceFD, buffer, bufferSize);
因为sizeofbuffer是指针的大小,而不是它指向的对象的大小。因为您正在使用mallocing,所以需要提供这个
附言:
字符缓冲区[bufferSize/sizeofchar]
这有点让人畏缩。Sizeofchar为1。char缓冲区[bufferSize/Sizeofchar];-你认为你有多少堆栈空间?我会使用malloc而不是VLA.bufferSize/sizeofchar。。。sizeofchar定义为1,因此除法是没有意义的。而且,是的,除非bufferSize总是一个相当小的值,否则您可能希望使用malloc而不是VLA。不是文件太大,而是bufferSize很可能太大。@Regicide ulimit-a将告诉您程序可以使用多少堆栈空间。您也可以尝试增加它。问题被标记为选项1是不可能的,因为要求bufferSize为变量。选项2不可能,因为向量不在c中。无论如何,谢谢你:现在它被标记了C。我发现它和萨胡一样:它被标记为C++。如果你正在监视新的C++问题,它会出现。如果你没有注意到标签被移除了。。。嗯,你可能给出C++答案。如果你这样做,确保你使用FuffBuffe;在函数返回之前。否则,每次调用该函数时,您的程序都会出现内存泄漏。我已经在回答中编辑了这个,我只是太快了。尽管如此,还是要谢谢你。嗯,我想我们都在某个时候犯过错误。我想重要的是不要重复
int geleseneBytes = read(sourceFD, buffer, sizeof(buffer));
int geleseneBytes = read(sourceFD, buffer, bufferSize);
int geleseneBytes = read(sourceFD, buffer, sizeof(buffer));
To:
int geleseneBytes = read(sourceFD, buffer, bufferSize);