2016-07-05 6 views
1
char *test={"0x11","0x12","0x13","0x00","0x00"}; 
void change(char* test1, char* test2){ 
    strncpy(test[3], test1, 4); 
    strncpy(test[4], test2, 4); 
} 

chage("0x55","0x66"); 

文字を配列要素に直接割り当てることができます。ただし、メモリリークが発生します。だから私は代わりにstrncpy()を使う。C - strncpy用法 - segfault

あなたはそれを修正する方法を知っていれば教えてください。

+8

あなたのコンパイラの警告をオンに: '-pedantic -Wall -Werror -std = c11'。 –

+0

何らかの理由で、テストは文字列の配列(char **)で初期化されます。私はそれが最初のところでどのように機能するのだろうか。 –

+0

最後の行の多くの箇所で構文エラーが発生しないのでしょうか?(0x66は文字列ではなく数値であり、暗黙的に不正なポインタに変換される可能性があります) –

答えて

4

、少なくとも3つの2を使用すると、(1つの提案は、コンパイラの警告を有効にすることです - 彼らはしばしば「愚かな過ちを」拾う)セグメンテーション違反ここで取得することができますがあります。

問題がtestがおそらくmisdeclaredされていることで、それはおそらくされている必要があります:

char *test[]={"0x11","0x12","0x13","0x00","0x00"}; 

あなたはその配列内の最初のポインタでtestを初期化することを意味char*の配列とchar*を初期化 - どのtestが文字列リテラル"0x11"を指していることを意味するので、strncpytest[3]を引数として使用すると、ポインタに変換される1が送信されます(おそらくアドレスは0x31になります)。 strncpyは、許可されていない最も可能性のあるそのアドレスに書き込みをしようとするだろう。あなたは(それが文字列の終端ヌルですbecaseあなたがtest[4]にアクセスすることができます)許可されない文字列の終わりを超えてアクセスするように求められますtest[5]使用していた場合は、ここではほぼ第四理由がありました。

これらの問題を修正しても、test[3]test[4]は文字列リテラルを使用して初期化されるため、問題があります。その後strncpyは未定義の動作ですリテラル、文字列を変更しようとする - test[3]test[4]が読み取り専用メモリに常駐しているためセグメンテーション違反がある(それらが読み取り専用メモリにできるようにすることは、文字列リテラルを変更すると、未定義の動作である理由の一つです)。

testに書込み可能なコピーがあることを確認してください。これは、Cではそれほど単純ではないかもしれません。通常の解決策の1つは、手動で呼び出す必要がある機能を設定することですそれを切断test、もう1つは:

void init_test(void) { 
    int j; 

    for(j=0; j<sizeof(test)/sizeof(test[0]); j++) 
     test[j] = strdup(test[j]); 

} 

void init_fini(void) { 
    int j; 

    for(j=0; j<sizeof(test)/sizeof(test[0]); j++) 
     free(test[j]); 
} 
0

他の答えは一つの良い理由を与える(内容の文字列(文字列(n)はCPYのというん)を変更しようとすることはありません)。

"文字"を文字列として表現したいとは思っていません。特に最初の宣言がうまくいきません(文字列を文字列に割り当てる)。

これを確かめるには多くの作業が必要ですが、最初に "0x11"を '\ x11'(IEは実際に文字を使用)に置き換え、strncpyを単なる割り当てで置き換えますこれを直接割り当てることができます)、最後にchange関数のパラメータを変更して文字列ではなく文字を取得します。