Shammer's Philosophy

My private adversaria

関数間での文字列データのやりとり

文字列を返す関数 - Shammerismでは、関数間でデータをやりとりする際にヒープを使用した。これが普通と思っていたが、単純に

char * test1(){
    char * v = "0123456789";
    return v;
}

で、呼出元は 0123456789 を把握できた。関数の終了と同時に v の内容もクリアされてしまうと思ったがそうでもないようだ。ただ、char * v を char v[] とすると、関数の終了と同時に v の内容もクリアされてしまうという趣旨の Warning が出た。こっちはまあ想定通り。char * v で宣言したものが返せるのはなぜだ?

char * test(){
    char v[] = "0123456789";
    return v;
}

全体は以下のような感じ。test2 の引数を参照型(&を付与)にすれば問題なく動作するのではないかと思ったけれども、実際はそうはならなかった。

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

char * test1(){
    char * v = "0123456789";
    return v;
}

// Compiling this function receives following message.
// warning: function returns address of local variable [enabled by default]
// char * warning(){
//     char v[] = "0123456789";
//     return v;
// }

// No compile warning, 
// but changing value is not affected the function to invoke this function.
void test2(char * v){ 
    v = "ABCDEFG";
}

// No compile warning
// but changing value is not affected the function to invoke this function.
// This is very close to test2().
// void test3(char v[]){
//     v = "ABCDEFG";
// }

// This function receives the following message,
// warning: assignment makes integer from pointer without a cast.
// void warning(char * v){
//     *v = "ABCDEFG";
// }

// This function receives the following message.
// error: lvalue required as left operand of assignment
// void error(char * v){
//     &v = "ABCDEFG";
// }

int main(int argc, char * args[]){
    printf("test1 returns %s\n", test1());
    char array[10];
    printf("char array[10];\n");
    test2(array);
    printf("test2(array);\n");
    printf("After test2(array), array value is %s\n", array);
    test2(&array[0]);
    printf("test2(&array[0]);\n");
    printf("After test2(&array), array value is %s\n", array);
    return 0;
}