ショッピングモール  Personal Health / Men's Health ( Impotence )


掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板1

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.4846

関数内の memcpy について
投稿者---igo(2005/11/12 21:18:20)


自作の関数内で、memcpy を使用して配列をコピーしたいのですが、0 番目のデーターしかコピーされません。

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

void cpy(int dt1[], int dt2[]);

int main(void)
{
    int i;
    int dt1[3] = {1, 2, 3};
    int dt2[3] = {10, 20, 30};
  
    cpy(dt1, dt2);

    return 0;
}

void cpy(int dt1[], int dt2[])
{
    int i;
    
    memcpy(dt2, dt1, sizeof(dt1));

    for (i = 0; i < 3; i++) 
        printf("%d  %d\n", dt1[i], dt2[i]);
}

どなたか、原因がわかる方がいらっしゃいましたら、教えていただけないでしょうか?
よろしくお願いします。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:関数内の memcpy について 4847 επιστημη 2005/11/12 21:23:54
<子記事> Re:関数内の memcpy について 4848 まきじ 2005/11/12 23:25:56
<子記事> Re:関数内の memcpy について 4849 mana 2005/11/13 04:08:48


No.4847

Re:関数内の memcpy について
投稿者---επιστημη(2005/11/12 21:23:54)


>自作の関数内で、memcpy を使用して配列をコピーしたいのですが、0 番目のデーターしかコピーされません。

関数に配列を与えたとき、実際には先頭要素のポインタが渡されます。
なのでsizeof(dt1)はsizeof(int*)となり、配列の大きさは得られません。



この投稿にコメントする

削除パスワード

No.4848

Re:関数内の memcpy について
投稿者---まきじ(2005/11/12 23:25:56)


>sizeof(dt1)はsizeof(int*)となり、配列の大きさは得られません。

ので cpy() の引数でサイズを渡してやる必要があります。


この投稿にコメントする

削除パスワード

No.4849

Re:関数内の memcpy について
投稿者---mana(2005/11/13 04:08:48)


はじめまして。

>どなたか、原因がわかる方がいらっしゃいましたら、教えていただけないでしょうか?
>よろしくお願いします。

VC++等では配列a[3]について
aは「配列の先頭アドレス」を示し「配列分のサイズ」を持ちます
a[0]は「配列の0番目の要素のアドレス」を示し「配列要素[0]1個分のサイズ」を持ちます。
そして示している番地はa=a[0]となります。

επιστημη様やまきじ様のおっしゃっている
>sizeof(dt1)はsizeof(int*)となり、配列の大きさは得られません。
というのはポインタ型が(環境にもよりますが)一律4バイトであり
どんな型のポインタでもポインタであれば全て同じ4バイトのサイズに
なるので、実態のサイズなどを渡してやらなければならないということです。

#長々書きましたがこんな感じで。。。


この投稿にコメントする

削除パスワード

No.4850

Re:関数内の memcpy について
投稿者---とおりすがり(2005/11/13 10:23:38)


>VC++等では配列a[3]について
>aは「配列の先頭アドレス」を示し「配列分のサイズ」を持ちます

違います。
 int a[3];
に対して、aは"int[3]"という型(要素数3のint配列)を持ちます。
sizeof(a)は、このint[3]という型のサイズ(=大抵12)が得られるのです。
式中で、配列への先頭アドレスになるというのは、その後の変換によるものです。
http://www.amy.hi-ho.ne.jp/~lepton/program/p3/prog327.html

>a[0]は「配列の0番目の要素のアドレス」を示し「配列要素[0]1個分のサイズ」を持ちます。

こちらは単純なミスかと思いますが、a[0]は要素そのものであって
アドレスではありません。なので、要素(int)のサイズが得られます。


この投稿にコメントする

削除パスワード

No.4851

Re:関数内の memcpy について
投稿者---igo(2005/11/13 11:11:10)


επιστημη様、まきじ様、mana様、とおりすがり様、早速、返信いただきありがとうございました。

皆様の返信を読んで以下のことがわかりました。
・配列を関数に渡したとき、先頭要素のポインタが渡さるため、配列の大きさはわからない。
・配列の大きさは、別の引数で渡す。

それで、下記のように修正して見ました。

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

void cpy(int dt1[], int dt2[], int n);

int main(void)
{
    int dt1[3] = {1, 2, 3};
    int dt2[3] = {10, 20, 30};

    cpy(dt1, dt2, 3);

    return 0;
}

void cpy(int dt1[], int dt2[], int n)
{
    int i;
    
    memcpy(dt2, dt1, n);

    for (i = 0; i < 3; i++) 
        printf("%d  %d\n", dt1[i], dt2[i]);
}
結果は、やはり 0 番目しかコピー出ませんでした。
ちなみに、自作関数内で memcpy を使わないで、for 文でコピーすることは可能なのですが。
自作関数内で memcpy を使う方法をもう少し詳しく教えていただけないでしょうか?
よろしくお願いします。


この投稿にコメントする

削除パスワード

No.4853

Re:関数内の memcpy について
投稿者---επιστημη(2005/11/13 11:31:22)


> cpy(dt1, dt2, 3);
> ...
> void cpy(int dt1[], int dt2[], int n)
> {
> int i;
>
> memcpy(dt2, dt1, n);

copyしなければならないのは n-byteではなく、n*sizeof(int)-byte。



この投稿にコメントする

削除パスワード

No.4854

Re:関数内の memcpy について
投稿者---mana(2005/11/13 11:33:56)


まずmemcpyの引数は
memcpy(コピー先アドレス,コピー元アドレス,コピーするサイズ);です
第3引数はサイズであって配列の要素数ではないことに注意してください。

int a[3]の要素数は3
int a[3]のサイズは12です(int型が4バイトとして)

なのでcpy(dt1, dt2, 3);
これで呼び出すとサイズが3バイト分しかコピーできません




この投稿にコメントする

削除パスワード

No.4855

Re:関数内の memcpy について
投稿者---igo(2005/11/13 15:51:38)


皆様のおかけで、解決することができました。

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

void cpy(int dt1[], int dt2[], int n);

int main(void)
{
    int n;
    int dt1[3] = {1, 2, 3};
    int dt2[3] = {10, 20, 30};

    n = sizeof(dt1);
    cpy(dt1, dt2, n);

    return 0;
}

void cpy(int dt1[], int dt2[], int n)
{
    int i;
    
    memcpy(dt2, dt1, n);

    for (i = 0; i < 3; i++) 
        printf("%d  %d\n", dt1[i], dt2[i]);
}


皆様のように助言できるように、もっと勉強します。
どうもありがとうございました。


この投稿にコメントする

削除パスワード

No.4856

Re:関数内の memcpy について
投稿者---mana(2005/11/13 17:27:41)


おめでとうごさいます。

ついでにべつの方法を載せてみます。
#include <stdio.h>
#include <string.h>

void cpy(int dt1[], int dt2[], int n);

int main(void)
{
    int dt1[3] = {1, 2, 3};
    int dt2[3] = {10, 20, 30};

    cpy(dt1, dt2, 3);

    return 0;
}

void cpy(int dt1[], int dt2[], int n)
{
    int i;
    
    memcpy(dt2, dt1, n*sizeof(int));

    for (i = 0; i < 3; i++) 
        printf("%d  %d\n", dt1[i], dt2[i]);
}

今回のcpy関数は渡される配列がint型限定なのでコレでもいけるかなっと
これなら呼び出し側は配列の要素数を指定して呼び出せます。



この投稿にコメントする

削除パスワード

No.4857

Re:関数内の memcpy について
投稿者---igo(2005/11/13 18:38:51)


mana 様

何度も返信をいただき、ありがとうございました。
とても、勉強になりました。
また、お世話になることが有るかもしれませんが、そのときはどうぞよろしくお願いします。


この投稿にコメントする

削除パスワード

No.4852

Re:関数内の memcpy について
投稿者---mana(2005/11/13 11:15:38)


>>VC++等では配列a[3]について
>>aは「配列の先頭アドレス」を示し「配列分のサイズ」を持ちます
>
>違います。
> int a[3];
>に対して、aは"int[3]"という型(要素数3のint配列)を持ちます。
これはしりませんでした。
(考えてみれば確かにaが配列分のサイズを持つっていう説明はおかしいですね;)
ご指摘ありがとうございます。

>>a[0]は「配列の0番目の要素のアドレス」を示し「配列要素[0]1個分のサイズ」を持ちます。
>
>こちらは単純なミスかと思いますが、a[0]は要素そのものであって
>アドレスではありません。なので、要素(int)のサイズが得られます。
ごめんなさい。。。;
a[0]は「配列の0番目の要素」
&a[0]で「配列の0番目の要素のアドレス」
ですね。。

#大変勉強になりました。
#あまり関係ない部分で混乱させてごめんなさい;


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity