atoiと+でバグります

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
fly5728

atoiと+でバグります

#1

投稿記事 by fly5728 » 6年前

コード:

#include <stdio.h>
#include <stdlib.h>

int main(){
	int a;
	char c;
	a = 999990;
	c = '9';
	a += atoi(&c);

	printf("%d\n", atoi(&c));
	printf("%d\n", a);

	return 0;
}
これを実行すると
9
1000086
という結果になります。どうしてでしょうか。

box
記事: 2002
登録日時: 13年前

Re: atoiと+でバグります

#2

投稿記事 by box » 6年前

atoi()に渡す引数の型が違ってるようです。

コード:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int a = 999990;
    char *c = "9";

    a += atoi(c);
    printf("%d\n", atoi(c));
    printf("%d\n", a);
    return 0;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: atoiと+でバグります

#3

投稿記事 by みけCAT » 6年前

fly5728 さんが書きました:これを実行すると
9
1000086
という結果になります。どうしてでしょうか。
cには終端のナル文字が含まれていないので、範囲外の読み込みが発生し、未定義動作になります。
どうしてこの結果になるのかを調べるため、printfを追加した以下のコードを実行してみました。

コード:

#include <stdio.h>
#include <stdlib.h>

int main(){
	int a;
	char c;
	a = 999990;
	c = '9';
	printf("&c = %p, &a = %p, atoi(&c) = %d\n", (void*)&c, (void*)&a, atoi(&c));
	a += atoi(&c);

	printf("%d\n", atoi(&c));
	printf("%d\n", a);

	return 0;
}
結果は、

コード:

&c = 0x7ffefd1c3c3b, &a = 0x7ffefd1c3c3c, atoi(&c) = 96
9
1000086
となりました。
この環境では、たまたまaがcの直後に配置されているため、atoiはcを処理した後aに格納されているデータを読み出します。
a = 999990のとき、この値は16進数では0xF4236です。
従って、int型が4バイト、リトルエンディアンの環境だとすると、メモリ上のデータは

コード:

┏━┳━━━━━━━┓
┃c ┃a             ┃
┠─╂─┬─┬─┬─┨
┃39┃36│42│0F│00┃
┗━┻━┷━┷━┷━┛
となります。
従って、&cから始まる「文字列」は、ASCIIコードだとすると"96B(制御文字)"となります。
atoiの処理は無効な文字で止まるので、これは96に変換され、aは999990 + 96 = 1000086となります。
1000086は16進数で0xF4296なので、int型が4バイト、リトルエンディアンの環境の場合、メモリ上のデータは

コード:

┏━┳━━━━━━━┓
┃c ┃a             ┃
┠─╂─┬─┬─┬─┨
┃39┃96│42│0F│00┃
┗━┻━┷━┷━┷━┛
となり、\x96は数字として無効なので、この時&cから始まる「文字列」は9に変換されます。
box さんが書きました:atoi()に渡す引数の型が違ってるようです。
引数として渡しているデータの型はchar*であり、atoiが受け付ける引数の型はconst char*なので、型自体は間違っていません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

fly5728

Re: atoiと+でバグります

#4

投稿記事 by fly5728 » 6年前

お二人ともご返信ありがとうございます。
atoiについての理解が深まりました。とても助かりました。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: atoiと+でバグります

#5

投稿記事 by Dixq (管理人) » 6年前

atoiの理解というより、文字列の理解がまだ出来ていないようです。
今一度文字列について勉強してみて下さい。
タブルコーテーションとシングルコーテーションは使い方が違います。

返信

“C言語何でも質問掲示板” へ戻る