質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.02%

  • C#

    5759questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ポインタ メモリの領域確保

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 362

llddsas

score 5

unsafe public struct A
    {
        public int ID;
        public B B_Data;
    }

unsafe public struct B
    {
        public int num;
        public void* value;
    }

上記の構造体があるとします。これらの変数に値とアドレスを代入したいのですが、領域確保してそこにアドレスを代入の方法がわかりません。

int a = 7;

A* dataList = stackalloc A[sizeof(A) * 5];
B[] DataValue = new DataValue[5];
for (int i = 0; i < 5; i++)
            {
         dataList[i].B_Data = DataValue[i];
               dataList[i].ID = i;
               dataList[i].B_Data.num = 10 + i;
               dataList[i].B_Data.Value = (void*)&a;
            }

これでやると正しく領域確保が出来ていないため上手くできません。
どのようにしてやれば良いのでしょうか?
よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2017/11/17 17:18 編集

    C# のタグが付いてますが C または C++ の間違いですか? であればタグを訂正願います。C# で間違いないということなら何故ポインタを使っている(unsafe コードを使っている)のでしょう? あと、DataValue が定義不明です。

    キャンセル

回答 2

0

もう解決しているかもしれませんが、以下のコードで解決できると思います。

領域確保ができていないのでは、Bの配列(DataValue)の個々の要素が初期化されていないためです。
構造体の初期化を追加してください。

DataValue[i] = new B();

質問のコードに組み込むと以下のような形です。

            int a = 7;

            A* dataList = stackalloc A[sizeof(A) * 5];
            // 配列をnewしただけでは中の構造体は初期化されません
            B[] DataValue = new B[5];
            for (int i = 0; i < 5; i++)
            {
                // 各構造体を個別にnewしてください
                DataValue[i] = new B();
                dataList[i].B_Data = DataValue[i];
                dataList[i].ID = i;
                dataList[i].B_Data.num = 10 + i;
                dataList[i].B_Data.value = &a;
            }

            // - - - - - 値の確認用コード - - - - - - 
            for (var i = 0; i < 5; i++)
            {
                Console.WriteLine(dataList[i].ID); 
                Console.WriteLine(dataList[i].B_Data.num);
                Console.WriteLine(*(int*)dataList[i].B_Data.value);
            }

お力になれれば幸いです。

 参考

蛇足かもしれませんがC#で固定サイズの配列を扱う場合に、アンマネージを使わない方法が下のサイトに詳しく記載されています。

C#でレガシーな事をする方向けのまとめ

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

以下で十分でした。
A の初期化時に B_Data の中身も初期化されるので、 dataList[i].B_Data = ***; は不要です。

int a = 7;
A* dataList = stackalloc A[sizeof(A) * 5]
for (int i = 0; i < 5; i++)
{
    dataList[i].ID = i;
    dataList[i].B_Data.num = 10 + i;
    dataList[i].B_Data.value = (void*)&a;
}

for (int i = 0; i < 5; i++)
{
    Console.WriteLine(*(int*)(dataList[i].B_Data.value)); // 7
}

正しく領域確保が出来ていない

質問のコードでも問題なさそうですが、 dataList のアドレスを戻り値で返してませんか?
stackalloc はメソッドを抜けたら解放されてしまいます。
もし予想が正しいのなら、 System.Runtime.InteropServices.Marshal クラスの Alloc*** メソッドが必要です。
…が、きっと unsafe 無しでやりたいことを実現できるアプローチもありそうなので、経緯がわかるとまた変わってくると思います。

追記
すみません5ヶ月前の質問だったんですね…。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.02%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    linux 処理時間の表示

    C言語でLinuxを使っています。メモリを確保したりするプログラムなのですが、以下のプログラムを修正して 、5秒間で何回の入れ替えを行えるかを計測できるようにしてもらいたいです。初

  • 解決済

    改行区切りでの出力

    ランダムな整数を改行区切りで3個出力したくて以下のコードを打ってみたんですが間違いといわれました。どこが違うのか指摘お願いします  public class Main {  p

  • 解決済

    localstorageに格納しているオブジェクトの一部削除の方法

    localstorageに下記オブジェクト(datalist)が保存してあるとして、 var datalist = { data1: "hoge1", data

  • 解決済

    List内の重複削除及びソート

    List内の重複削除及びソート(小さい順)を行いたいのですが、上手くいきません。 LINQを使い削除までは何とかできたのですが、ソートがうまくいきません。 LINQの使い方もこ

  • 受付中

    intをbyte[]にしたいです。

    前提・実現したいこと こんばんは。いつもたいへんお世話になります。 byte[] bytes = {0,0,24,40}; var size = 16777216 * byte

  • 受付中

    リスト構造と待ち行列

    リスト構造と待ち行列をしたいのですが、よくわかりません。 おすすめのサイトや説明おねがいします。 #include <stdio.h> #include <stdlib.h>

  • 解決済

    再帰的なメソッドをスタックを使って非再帰的に書くには?

    前提・実現したいこと IntStackはInt型のスタック、先入れ後出しのStackです。 static void recur3(int n){ if(n > 0){ recu

  • 解決済

    for文の中にある最大値の取得方法

    前提・実現したいこと 某サイト内で出されている問題について 「forループを用いて、1から100までの乱数を5回発生させ、表示し、終了後その中の最大値を表示しなさい。」 という問題

同じタグがついた質問を見る

  • C#

    5759questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。