2017-01-19 16 views
0

Cでポインタと配列の宣言を試していて、意味をなさない結果が出ています。 64をベースにするバイナリに変換し、この関数を考えてみましょう:ポインタ宣言とCの有限配列宣言

char *bin2b64Str(char *binStr) { 
    char finalb64str[256]; 
    char *paddedBin; 
    int i, r, t, loops; 
    char buffer[] = { '0', '0', '0', '0', '0', '0', '\0' }; 

    int count = 0; 
    r = 6 - strlen(binStr) % 6; 
    if (r != 6) { 
     loops = (int)strlen(binStr)/6 + 1; 
     paddedBin = (char*)malloc(((strlen(binStr) + r) + 1) * sizeof(char)); 
     memmove(paddedBin, &buffer[6 - r], r); 
     memmove(&paddedBin[r], binStr, strlen(binStr) + 1); 
    }else{ 
     loops = (int) strlen(binStr)/6; 
     paddedBin = (char*)malloc(((strlen(binStr)) + 1) * sizeof(char)); 
     memmove(paddedBin, binStr, strlen(binStr) + 1); 
    } 

    char b64str[strlen(binStr) + r + 1]; 
    for (i = 0; i < loops; i++) { 
     char sextet[7]; 
     ++count; 
     if (count != loops) { 
      memcpy(sextet, &paddedBin[6 * i], 6); 
      sextet[6] = '\0'; 
     } else { 
      memcpy(sextet, &paddedBin[6 * i], 7); 
      sextet[6] = '\0'; 
     } 
     b64str[i] = bin2b64Char(sextet); 
    } 
    memcpy(finalb64str, b64str, loops); 
    finalb64str[loops] = '\0'; 

    return finalb64str; 
} 

このコードは、私のためにうまく動作しますが、私が代わりに最初の行を変更した場合:

char *finalb64str 

として最後のmemcpyの行を置き換えます。

finalb64str = b64str; 

これは惨めに失敗します!私は全く理解していません。なぜこうなった?私はポインタと配列についてすべてを研究してきましたが、私が見つけたことは何も私のためにこれに答えるようです。

+0

なぜあなたは 'malloc'から戻り値をキャストしていますか? –

+1

@Mattそれは両方とも無効です:配列の記憶域の寿命は、関数の戻りで終了します。配列を静的にし、 'malloc()'スペースを返すか、呼び出し側が指定したバッファを埋めます。 – Ctx

+3

バイナリデータに 'strlen()'を使用することは疑わしいです。最初のnullバイトでカウントを停止しますが、バイナリデータは任意のポイントでnullバイトを持つことがあります。 –

答えて

0
char b64str[strlen(binStr)+r + 1]; 

は、関数にローカルなスタックに割り当てられた配列であり、関数が返されたときの参照は無効です。あなたはあなただけのローカルに宣言された配列にローカル変数を割り当てる終わり

finalb64str = b64str; 

を書くとき

、返されたアドレスは無効になります。

外部にb64strが表示されるようにするには、ストレージをmallocしてポインタを戻すのが最も簡単です。

char* b64str = malloc(strlen(binStr)+r + 1); 
... 
return b64str;