2

私が存在すると約束する理由により、入力を 1 文字ずつ読み取り、文字が特定の基準を満たしている場合は、動的に割り当てられたバッファーに書き込みます。この関数は、指定された文字列の「末尾」に指定された文字を追加します。バッファから読み取るとき、最初の「サイズ」文字を読み取ります。

void append(char c, char *str, int size)
{
 if(size + 1 > strlen(str))
        str = (char*)realloc(str,sizeof(char)*(size + 1));
 str[size] = c;
}

この関数は、さまざまな開発の反復により、「破損した二重リンク リスト」、「二重解放または破損」などのエラーを生成しました。以下は、append の使用方法のサンプルです。

// buffer is a string
// bufSize is the number of non-garbage characters at the beginning of buffer
char *buft = buffer;
int bufLoc=0;
while((buft-buffer)/sizeof(char) < bufSize)
    append(*(buft==),destination,bufLoc++);

通常、一見任意の数の文字に対して機能し、エラーで中止されます。2 番目のコード スニペットが何を行っているかが明確でない場合は、バッファーからコピー先の文字列にコピーしているだけです。これにはライブラリメソッドがあることは知っていますが、時々正確にコピーされるものをもう少し細かく制御する必要があります。

洞察をお寄せいただきありがとうございます。私は困惑しています。

4

2 に答える 2

4

この関数は、バッファに文字を追加しません。

void append(char c, char *str, int size)
{
    if(size + 1 > strlen(str))
        str = realloc(str, size + 1);
    str[size] = c;
}

まず、何strlen(str)ですか?「それはの長さですstr」と言うことができますが、それはいくつかの非常に重要な詳細を省略しています。長さはどのように計算されますか?Easy- strNULで終了する必要があり、その中の最初のバイトstrlenのオフセットを見つけます。NULバッファの最後にNULバイトがない場合、strlenその長さを見つけるために使用することはできません。

通常、バッファの長さを追跡する必要があります。再割り当ての数を減らすために、バッファサイズとその中のデータ量を別々に追跡します。

struct buf {
    char *buf;
    size_t buflen;
    size_t bufalloc;
};

void buf_init(struct buf *b)
{
    buf->buf = NULL;
    buf->buflen = 0;
    buf->bufalloc = 0;
}

void buf_append(struct buf *b, int c)
{
    if (buf->buflen >= buf->bufalloc) {
        size_t newalloc = buf->bufalloc ? buf->bufalloc * 2 : 16;
        char *newbuf = realloc(buf->buf, newalloc);
        if (!newbuf)
            abort();
        buf->buf = newbuf;
        buf->bufalloc = newalloc;
    }
    buf->buf[buf->buflen++] = c;
}

別の問題

このコード:

str = realloc(str, size + 1);

strinの値を変更するだけです。呼び出し元の関数appendのの値は変更しません。str関数の引数は関数に対してローカルであり、それらを変更しても関数の外部には影響しません。

マイナーなクイズ

これは少し奇妙です:

// Weird
x = (char*)realloc(str,sizeof(char)*(size + 1));

(char *)キャストは不要であるだけでなく、実際にはエラーをマスクする可能性があります。インクルードを忘れた場合でも、<stdlib.h>キャストによってコードをコンパイルできます。残念。

そしてsizeof(char)、定義上、1です。だから気にしないでください。

// Fixed
x = realloc(str, size + 1);
于 2012-11-11T11:32:54.437 に答える
0

あなたがするとき:

str = (char*)realloc(str,sizeof(char)*(size + 1));

str の変更は、呼び出し元の関数には反映されません。つまり、ポインターが値で渡されるため、変更は関数に対してローカルです。これを修正するには、str の値を返します。

char * append(char c, char *str, int size)
{
 if(size + 1 > strlen(str))
        str = (char*)realloc(str,sizeof(char)*(size + 1));
 str[size] = c;

 return str;
}

または、ポインタをアドレスで渡すことができます。

void append(char c, char **str, int size)
{
 if(size + 1 > strlen(str))
        *str = (char*)realloc(*str,sizeof(char)*(size + 1));
 (*str)[size] = c;
}
于 2012-11-11T11:34:48.873 に答える