2012-02-08 17 views
1

私は朝からこれを修正するのに苦労してきました。値 'pd' pmは機能外で変更されません。誰かが間違いを教えてもらえますか?関数とmemcpyへの参照としてchar配列を渡す方法

void foo(u8 *pm, u8 *pd) 
{ 
    pm = "IWR "; 
    memcpy(pd, pm, sizeof(pm)); 
    printf("in foo pm = %s, pd = %s \n", pm, pd); 
} 

int main() 
{ 
    u8 pm[5] = "0"; 
    u8 pd[5] = "IWO "; 
    printf("pm = %s, pd = %s \n", pm, pd); 
    foo(pm, pd); 
    printf("after pm = %s, pd = %s \n", pm, pd); 
} 

fooへの呼び出しの後に私の最終的な出力がpm =(ヌル)とpd = "IWO" です。私は「pm」も価値を変えるだろうと思った。

(ここideone上のコードであるが、0ではなく(null)としてその場合pmプリント理由です。?)

pm = 0, pd = IWO 
in foo pm = IWR , pd = IWR 
after pm = 0, pd = IWR 
+0

[ヘッドポインタを変更見てみましょう]を見つけることができるはずですCまたはC++? (長さ) –

+0

C++でも文字列関数を使用したくない – swap

+0

ここでうまくいきますが、おそらく 'sizeof'というバグがあります。 –

答えて

1

テンプレートで参照によって配列を渡すことができる。

template<typename T, unsigned int Length1, unsigned int Length2> 
void foo(T(&pm)[Length], T(&pd)[Length2]) { 
    memcpy(pd, "IWR ", Length2 - 2); // - 2 for the NULL 
    pd[Length2 - 1] = 0; 

    printf("in foo pm = %s, pd = %s \n", pm, pd); 
} 

これは、前にfooと同じ方法で使用してください。これは、ポインタではなく配列でのみ機能することに注意してください。

pm = "IWR "; 

があなたの本来の機能で何もしない(ちょうどローカルポインタ変数を変更)し、この修正1(配列に割り当てることはできません)で動作しないこと

は注意してください。それをしたい場合は、memcpyも使用する必要があります。

テンプレートを使用したくない場合は、配列を関数に渡すと、各配列のサイズを関数に渡す必要があります(または、センチネル値を使用しますが、そうしないでください)参照で渡さずに)ポインタに崩壊し、sizeof(array)は配列のバイト数を返しますが、sizeof(pointer)はあなたが望むものと異なるポインタのバイト数を返します。

+0

それで、あなたはmemcpyをするためにサイズを渡さなければならないと言います。しかし、私はmemcpyなしでそれをすることはできますか? 基本的には、自分の値を変更して変更された値を与える関数です。しかし、あなたが投稿したコードの中でpass-by-ref – swap

+0

@swapをしなければならない部分では、私は失われています。配列の最初の要素に値を渡しています**、_ 。そのようにすれば、ポインターが指す配列のサイズを知る方法がないので、関数の引数としてサイズを渡す必要があります。 array_を_reference_で渡すと、関数の引数として渡さなくてもサイズを知ることができます( 'Length'テンプレート引数と' sizeof'の両方が機能します)。 –

+0

ああ..大丈夫です。しかし、私の無知は、参照としてchar配列を渡すことにあります。構文はどのように見えますか? – swap

4
  1. sizeof(pm)foo()は、ポインタのサイズです。あなたが想定しているように、配列のサイズではありません。
  2. pmは、あなたのプログラムに与えられているので、pdは確かに機能の外で変更されないことを意味すると思います。理由は、pmは変更されません。なぜなら、C(そしてあなたが使っている方法ではC++)が値渡しの言語なのでです。 C FAQにはquestion about precisely your problemがあります。
0

こんにちはpm = "IWR"を実行することで、どの午後がconst参照を指しているかを変更しました。つまり、関数pm内のポインタpmを別の場所を指すように完全に変更しました。

if you do this inside the function your code would work as expected. See why its failing below. 


    pm[0] = 'I'; 
    pm[1] = 'W'; 
    pm[2] = 'R'; 

    before foo in main 
    ---------- 
    print pm "0\000\000\000" 
    print &pm == (u8 (*)[5]) 0x7fbffff7b0 

    in foo as soon as we enter 
    ------ 
    print pm = (u8 *) 0x7fbffff7b0 "0" (you are pointing to the same location as in main) 
    print pm = (u8 **) 0x7fbffff788 

    ----  pm = "IWR" --- 
    print pm = 0x400adc "IWR" (now pm is pointing to location in memory where const IWR is stored) 
    print &pm = (u8 **) 0x7fbffff788 

    ---back to main --- 
    print pm = "0\000\000\000" (we havent changed anything on location fff7bo so no affect) 
    print &pm $8 = (u8 (*)[5]) 0x7fbffff7b0 

Googleのためのリンクリストの先頭を変更すると、あなたは適切な説明に

cslibrary.stanford.edu/103/LinkedListBasics.pdf

関連する問題