これらの2つのバージョンでは:
//VERSION 1
char *c=malloc(10);
c[0]='h';
c[1]='i';
c[2]='\0';
c[3]='l';
printf("%s\n",c);
期待どおりの結果が得られていhi
ます。つまり、印刷されています。
今これで:
//VERSION 2
char *c;
size_t siz=8;
c=malloc(sizeof(char)*(siz+1)); //char size is 1 byte on system
getline(&c,&siz,stdin);
c[siz]='\0';
printf("%s\n",c);
上の入力値「ハローワールド」を出力するには、「ハロー世界である-私はそれが(それがに設定されている9バイト目を読んだ後、何も印刷されないことを期待していました\0
)。
なぜ2つに違いがあるのですか?
c
バージョン2のポインターがポイントするように作成されてstdin
おり、「\ 0」の変更がストリーム内でそのように機能しないために発生していますか?はいの場合、コンパイラが警告またはエラーを発行するのはなぜですか?
コメントであなた自身が指摘したようにgetline
、ストリームからの行が指定されたバッファのサイズを超えた場合にバッファを再割り当て(または割り当て)する必要があるかどうかを確認するためにポインタとサイズの引数をチェックします(NULL
サイズ0のバッファはプレーンです)再割り当ての代わりに割り当て)。これが発生すると、新しいバッファーに一致するようにポインターとサイズの両方の引数が変更されます(引数自体だけでなく、値ではなくバッファーポインターとサイズの引数にポインターを渡したことに注意してください)。
したがって、あなたの例では、サイズ9文字(あなたの場合は9バイト)のバッファを割り当てた後。あなたのc
ポインタが少なくとも9でいくつかのメモリに設定されている利用可能なバイトとsiz
同じように長い(改行を含む)8文字以上の行を入力した後、しかし、まだ8で"hello world\n"
バッファが文字列全体に合うように再割り当てされ、"hello world\n\0"
すなわち13バイト、 ANDサイズ引数は13に変更されます。したがって、がgetline
戻ると、c
この新しいバッファを指し、siz
13になります。nullの終了を追加する必要はありませんgetline
(成功した場合)。次に、バッファの終わりを超えてアクセスしているときに(文字列を作成して)例外をトリガーしなかった設定c[13]
を'\0'
行います"hello world\n\0\0"
。
探している結果については、マクロのように、元のサイズを脇に置いておきます。
#define SIZE 8
char* c;
size_t siz = SIZE;
c = malloc(sizeof(char) * (siz +1));
getline(&c, &siz, stdin); // if you type something longer than 8 bytes including new line, it will trigger the realloc and siz will be changed
c[SIZE] = '\0'; // prematurely end the string at 8 bytes
printed("%s\n", c); // now you'll get shorter strings, noting siz will still keep the full length for you
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加