Shammer's Philosophy

My private adversaria

文字列の連結-snprintf_ver1

文字列の連結 - Shammerismでいろいろ悩んでいたが、どうやらsnprintfを使用するのが一番よさそうだ。まず、snprintfを使用しない力技バージョン。

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

char * returnString(char * v){
    char * response;
    response = (char *)malloc(strlen(v) + 5);
    response[0] = '[';
    response[1] = 'R';
    response[2] = 'E';
    response[3] = 'S';
    response[4] = ']';
    int i = 5;
    int last = strlen(v) + 5;
    for( i ; i < last ; i++ ){
	response[i] = v[i - 5];
    }

    return response;
}

int main(int argc, char * args[]){
    char * v1 = "0123456789";
    char * v2 = returnString(v1);
    printf("v1 value is %s.\n", v1);
    printf("v2 value is %s.\n", v2);
    printf("v1 address is %p.\n", v1);
    printf("v2 address is %p.\n", v2);
    free(v2);
    return 0;
}

もともとの文字列、つまり、引数で渡された文字列と「[RES]」という文字列を組み合わせるもの。配列を操作しているから無駄に長い。。。これは、snprintfを使用して以下のように書けるらしい。

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

char * returnString(char * v){
    char response[] = "[RES]";
    snprintf(response, sizeof(response), v);
    return response;
}

int main(int argc, char * args[]){
    char * v1 = "0123456789";
    char * v2 = returnString(v1);
    printf("v1 value is %s.\n", v1);
    printf("v2 value is %s.\n", v2);
    printf("v1 address is %p.\n", v1);
    printf("v2 address is %p.\n", v2);
    free(v2);
    return 0;
}

実行すると、

$ ./a.out
v1 value is 0123456789.
v2 value is S}&#65533;&#65533;.
v1 address is 0x40071c.
v2 address is 0x7fff884ffc50.
...
Aborted

v2 value も変だし、Abort してしまった、、、何かが間違えている。と思ってよくみると、ローカル変数を返している。これで変なところにアクセスされた可能性が高い。これは修正しなければ。。。