雑記帳
ここはhideyosiの雑記帳です。テケトーに書き散らしてるだけなので間違っていたりとは普通にしてます。信用度は相当低いことをあらかじめご了承を。またご覧のようにWikiを使ってますが、hideyosi意外は書き込めません。

strncat関数がおかしいぞ!? anchor.png

本家の板にて、うっちゃんが発見した挙動不審部。

以下がそのソース。

char* strncat (char *d, const char *s, size_t sz)
{
char *tmp = d;

while ('\0' != *d)
d++;

while ('\0' != *s) {
if (0 == sz)
break;
sz--;
*d++ = *s++;
}

if (sz)
*d = '\0';

return tmp;
}
Page Top

アドバイスの検証 anchor.png

はいそうです! アホなんで書かないとわかんないんです〜  orz

なぜこうなるのか?について、うっちゃんが丁寧に教えてくれたのだ♪ http://osask.net/v/index.php?topic_id=16#post_id239

while ('\0' != *d)
d++;

これはなにをやってるのか。文字列sのオケツにポインタを進めていると。(仮に文字列の途中に0x00があれば、そこをオケツとするわけ。

char str[4] = { 'a', '\0', 'H', '\0' };
文字列str
0123
'a'0x00'H'0x00

上記のwhileによってこういう状態になって、次の処理に移る・・・

文字列str
0123
'a'0x00'H'0x00
while ('\0' != *s) {
  if (0 == sz)
      break;
  sz--;
  *d++ = *s++;
}

文字列sはこうなっている。

文字列s
0123
'b''b''b'0x00

szが1なので、whileループは一回だけ処理される

         //szは1
          while ('\0' != *s) {
  ↑           if (0 == sz)
  │              break;
  │           sz--;
  │           *d++ = *s++;
  │      }
  │               
  │          //szは0
  │     //よーし!ループするぞ!
  └────────┘
              //szは0
  ┌──┐    while ('\0' != *s) {
  │    │           if (0 == sz)
  │    │              break;
  │    │           sz--;
  │    │           *d++ = *s++;
  │    │      }
  │    │               
  │    │        //szは0
  │    │        //よーし!ループするぞ!
  │    └────────┘
  └──────────┐
                        ↓
                 //なんだSZはもうゼロじゃん。なにもせんで次へ・・・

Last-modified: 2012-10-22 (Mon) 22:05:13 (GMT) (2853d) by hideyosi