Shammer's Philosophy

My private adversaria

itoa 改良版-20110217

とりあえず、何か memset が悪さをしているということまではわかった。問題なく動作する環境もあったので何かのバグかもしれないと期待しつつ、、、でも結局原因は特定できず。malloc と memset を組み合わせると問題になるので、calloc を使ってみた。どのみち、memset で確保した領域を 0 で初期化するなら calloc でも変わらないはずなので。ほとんどitoa 実装 - Shammerismと同じだが。

char * itoa(int x){
    char * value;
    // int max is 2147483647, this is 10 digit.
    int i, j, digit, result;
    int length = -1;
    int rest = abs(x);
    // Check number of digit
    for( i = 10 ; 0 <= i ; i-- ){
	digit = 1;
	for( j = i ; j != 0 ; j-- ){
	    digit = 10 * digit;
	}
	if( (rest / digit) != 0 ){
	    length = i;
	    value = (char *)calloc((length + 1), sizeof(char));// 1 means '\0'
	    break;
	}
    }
    // Fill in the char
    for( i = length ; 0 < rest ; i-- ){
	digit = 1;
	for( j = i ; j != 0 ; j-- ){
	    digit = 10 * digit;
	}
	result = rest / digit;
	rest = rest % digit;
	int index = length - i;
	switch (result) {
	    case 0:
		*(value + index) = '0';
		break;
	    case 1:
		*(value + index) = '1';
		break;
	    case 2:
		*(value + index) = '2';
		break;
	    case 3:
		*(value + index) = '3';
		break;
	    case 4:
		*(value + index) = '4';
		break;
	    case 5:
		*(value + index) = '5';
		break;
	    case 6:
		*(value + index) = '6';
		break;
	    case 7:
		*(value + index) = '7';
		break;
	    case 8:
		*(value + index) = '8';
		break;
	    case 9:
		*(value + index) = '9';
		break;
	    default:
		// Do nothing
		break;
	}
    }
    if( x < 0 ){
	length = strlen(value);
	char temp[length];
	for( i = 0 ; i < length ; i++ ){
	    temp[i] = value[i];
	}
	temp[length] = '\0';
	length = length + 1;// for minus
	free(value);
	value = (char *)calloc((length + 1), sizeof(char));//plus 1 is for '\0'
	value[0] = '-';
	for( i = 0 ; i < length ; i++ ){
	    // + 1 is for '-'
	    *(value + 1 + i) = temp[i];
	}
    }
    value[length + 1] = '\0';
    return value;
}

int main(int argc, char* args[]){
    printf("%s\n", itoa(12345));
    return 0;
}

これで、2 つの環境で Segmentation fault にならずに実行できた。