1

cpに似た動作をする単純なプログラムがあります。このプログラムは、穴を含め、あるファイルから別のファイルにコンテンツをコピーします。単純な実装による単純なセマンティクス。その主な部分を以下に示します。問題は、以下にマークされている行なしでコンパイルして実行すると(GCC 4.7.1 Arch Linux)、2番目のファイルがランダムなバイトシーケンスで数秒間いっぱいになり、セグメンテーション違反で終了することです。しかし、マークされた行を挿入すると(これは、現在書き込まれているバイト数をttyに出力するだけです-すべてOKです)。たとえばprintf("Hello World!\n")、代わりに使用すると、まだ壊れています。

ここで何が起こっているのですか?このエラーの原因となるプログラムのセマンティクスとは関係のないライブラリ関数はどのように機能しますか?

#include "tlpi_hdr.h" //declares errExit and usageErr
#include <malloc.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

#define BUF_SIZE 1024

int main(int argc, char **argv)
{
    if ( argc != 3 )
        usageErr("cp_self source dest");
    int fd_source, fd_dest, bytes;
    char *buf, *cur;
    buf = malloc(BUF_SIZE);
    FILE *str;

    if ( ( fd_source = open(argv[1], O_RDONLY) ) == -1 )
        errExit("open(%s)", argv[1]);
    if ( ( fd_dest = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO) ) == -1 )
        errExit("open(%s)", argv[2]);
    if ( ( str = fdopen(fd_dest, "w") ) == NULL )
        errExit("fdopen(%d, 'w')", fd_dest);
    while ( ( bytes = read(fd_source, buf, BUF_SIZE) ) != 0 )
    {
        int dbg_cntr = 0;
        cur = buf;
        while ( cur != buf + bytes )
        {
            //printf("%d\n", dbg_cntr++); this line
            if ( *cur == '\0' )
            {
                if ( fflush(str) != 0 )
                    errExit("fflush(%d)", str);
                if ( lseek(fd_dest, 1, SEEK_CUR) == (off_t) -1 )
                    errExit("lseek(%d, 1, SEEK_CUR)", fd_dest);
            }
            else
            {
                if ( fprintf(str, "%c", *cur) != 1 )
                    errExit("fprintf(%d, %c)", str, *cur);
            }
            ++cur;
        }
    }
}

コード全体が追加されました。

4

3 に答える 3

3

read()エラーが発生すると戻り-1ます。この場合、buf + bytesは未満になり、読み取りが許可されていないメモリを指すcurまで無限ループが発生し、セグメンテーション違反が発生します。cur

于 2012-08-17T18:17:18.280 に答える
1

dbg_cntr++変数をインクリメントします。スコープがどのようなものかはわかりませんが、プログラムの他の部分に影響を与えている可能性があります。このステートメントを。なしで保持してみてくださいprintf

于 2012-08-17T18:05:41.057 に答える
1

readを呼び出すとbuf、特に何かを指すように初期化されていないため、未定義の動作が発生します。

于 2012-08-17T18:28:34.313 に答える