0

C# でリンク リストを使用した多項式に関する単純なプログラムを作成しています。私が抱えている問題は、for ループで新しい構造体 (ノード) を作成するたびに、前のノードが指定されたのと同じアドレスを指定することです。どうすれば修正できますか?ここに私の構造体があります:

struct poly { public int coef; public int pow; public poly* link;} ;

そして、問題が発生する場所は次のとおりです。

for (; i < this.textBox1.Text.Length; i++)
{
    q = new poly();
    ...
    p->link = &q;
}

でも&q相変わらず!

アップデート:

さらに明確にするために、完全なコードを次に示します。

namespace PolyListProject
{
    unsafe public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();   
        }

        struct poly { public int coef; public int pow; public poly* link;} ;
        poly *start ;
        poly *p;

        private void button1_Click(object sender, EventArgs e)
        {
            string holder = "";
            poly q = new poly();
            start = &q;
            int i = 0;
            while (this.textBox1.Text[i] != ',')
            {
                holder += this.textBox1.Text[i];
                i++;
            }
            q.coef = int.Parse(holder);
            i++;
            holder = "";
            while (this.textBox1.Text[i] != ';')
            {
                holder += this.textBox1.Text[i];
                i++;
            }
            q.pow = int.Parse(holder);
            holder = "";
            p = start;
            //creation of the first node finished!
            i++;
            for (; i < this.textBox1.Text.Length; i++)
            {
                q = new poly();
                while (this.textBox1.Text[i] != ',')
                {
                    holder += this.textBox1.Text[i];
                    i++;
                }
                q.coef = int.Parse(holder);
                holder = "";
                i++;
                
                while (this.textBox1.Text[i] != ';'&& i < this.textBox1.Text.Length-1)
                {
                    holder += this.textBox1.Text[i];
                    if (i < this.textBox1.Text.Length-1)
                        i++;
                }
                q.pow = int.Parse(holder);
                holder = "";
                p->link = q;
            }
            p->link = null;
        }
    }
}

私たちの教授は私たちに C でそれを行うように頼んだが、C# で行うことに決めたが、実際に C を使用する人はもう誰もいないので、C の外観を与えることにした。

4

3 に答える 3

2

わかりました、あなたは間違いなく C# ではなく C++ を使用しているので、C++ に関して答えます。

この関数では、q変数は (私が推測しているように)、この関数に対してローカルなポインターです。つまり、そのアドレスは変更されません。

問題は、ポインタのアドレスを に割り当てていることですp->linknew poly()既に (これはアドレスです!) を返すのでpoly*、アドレスは必要ありません。

これを試して:

q = new poly();
 ... 
p->link = q;
于 2010-05-16T11:45:32.747 に答える
1

問題は解決しました:)このように:(ただし、qは代わりにポインターです)

IntPtr newP = Marshal.AllocHGlobal(sizeof(poly));
poly* q = (poly*)newP.ToPointer();
// ......
p->link = q;
于 2010-05-17T17:15:32.870 に答える
0

&q の問題は、メソッドの実行中に構造体インスタンス q が実行スタックに存在することです。new() 構文を使用しても、構造体はまだスタックにあります。そのため、アドレスは常に同じです (関数から戻ると無効になります)。ヒープ (GC ヒープではなく、特別なアンマネージ メモリ領域) 上の構造体へのポインターを取得する場合は、次のようにします。AllocHGlobalを使用してメモリを割り当ててから にキャストするIntPtr必要があり(poly*)ます。これは管理されていないメモリであるため、忘れずに解放する必要があります。

一般に、このように C# を使用しようとするのは非常に悪い考えだと思います。C# と C++ のプログラマーを混乱させるからです。Unsafe 構文は、基になるメモリへの高速アクセスが必要な非常にまれな境界ケースや、特定の相互運用シナリオで役立ちます。それを使用して C スタイルのポインターを使用してデータ構造を実装することは、まったく間違っています。


上記が不明な場合に備えて、具体例を次に示します。この操作q = new poly();は、q (スタック上のローカル変数) の内容を新しく初期化された poly() に置き換えるだけです。これは、新しいインスタンスを割り当てるというよりも、メモリをクリアすることに似ています。紛らわしいのは、C++ では、割り当てに関して構造体とクラスに違いがないためです。C++ の new() は、常にヒープ上に割り当てられます。C# では、割り当て場所は通常、使用法ではなくtypeによって決定されるため、値型 (構造体) で new() を呼び出す場合、これは初期化の省略形であり、ヒープにメモリを割り当てません。


あなたは「修正済み」について質問しましたが、安全でない C# を基本的に C と同じだと考えて使用すべきではない理由の非常に良い例があります。C# では、参照はポインターと同じではありません。大きな違いの 1 つは、C# 参照はガベージ コレクションであるため、GC はほぼいつでもプログラムの実行をハイジャックし、すべての参照を新しいメモリ ロケーションを指すように置き換えることができることです。ポインターを介して参照されるメモリを参照する安全でないコードを使用すると、ポインターによって参照されるオブジェクトが、ポインターが更新されずに移動する可能性があります。これに対処するために、特定のインスタンスを「固定」としてマークして、GC が移動しないようにすることができます。C# コンパイラは、ユーザーを自分自身から守ろうとしています。

于 2010-05-16T13:28:05.460 に答える