Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 复制程序适用于小文件,在较大文件上出现分段错误_C - Fatal编程技术网

C 复制程序适用于小文件,在较大文件上出现分段错误

C 复制程序适用于小文件,在较大文件上出现分段错误,c,C,为了学习一些低级C魔法,我尝试实现不同的方法将一个文件的内容复制到另一个文件 下面的方法使用一个缓冲区,我在其中保存数据块,例如512字节。然后我从这个缓冲区写入目标文件。据称,这比直接复制整个文件更有效 当我使用一个小的缓冲区(例如512字节)时,这个效果很好。 如果我使用一个大的缓冲区,例如10000000字节,大约10MB,我会得到一个分段错误 我正在Ubuntu上运行。 我试过和malloc合作,但没有什么真正适合我的。一旦我知道了,我想解决问题会很容易 根据我的debbuger,错误在

为了学习一些低级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);