1

C ++でプログラムを開発していますが、次のコードを実行すると次のエラーが発生します。

short readshort() {
    short val=0;
    (&val)[1]=data.front(); data.pop_front();
    (&val)[0]=data.front(); data.pop_front();
    return val;
}

これは私が得るエラーです:

Run-Time Check Failure #2 - Stack around the variable 'val' was corrupted.

ここで、「データ」はstd ::listdataで定義されていることを述べておきます。

何が問題なのかはわかっていると思いますが、簡単な解決策は思いつきません。このエラーは、ポインタとしてではなく、スタックに格納されている「val」が原因であると思います。「val」でデータポインタにアクセスしようとすると、このエラーが発生します。

私が考えた解決策は、次のように「val」を割り当てることでした。

short readshort() {
    short* val=new short;
    val[1]=data.front(); data.pop_front();
    val[0]=data.front(); data.pop_front();
    return *val;
}

しかし、関数の外で毎回削除せずに「val」を返すと、それを削除する方法がわかりません。これをC++でメモリリークなしで実行できる方法はありますか?以前、 "(&val)[1]"を使用して可変型(たとえばshort)をバイトに分割する人を見たことがありませんでしたが、これは多くの問題を引き起こしたためなのか、それとも既知の方法ではないのか疑問に思いました。 ?

本当の質問に戻ると、どうすればこれらの2バイトを短い(または大きなデータ型)にすることができますか?そして、私が試したものよりもこれを行うためのより良い方法はありますか?

最後に、Javaには、メモリリークを自動的にクリーンアップする自動ガベージコレクターがあることを知っています。C ++は同じ種類のデバイスを提供しますか?スマートポインタについて何か聞いたのですが、それが何であるかわかりません;)

4

4 に答える 4

2

これは安全で簡単です:

int16_t readshort()
{
    union { int16_t s; char val[2]; } u;
    u.val[1]=data.front(); data.pop_front();
    u.val[0]=data.front(); data.pop_front();
    return *(int16_t*)u.val;
}
于 2013-03-01T23:11:24.977 に答える
1

(&val)[1]=data.front()(&val)[1]次のメモリ位置を書き込んでいることによるエラーvalは定義されていません。

(&val)[i]意味=この細かい*(&val + i )
(&val)[0]意味=しかし、あなたの宣言はvalの場所にしかアクセスできないため、これはエラーです。*(&val + 0 )*(&val)
(&val)[1]*(&val + 1 )short val

+----+----+----+---+---+----+----+----+---+----+ 
|val      |        |
+----+----+----+---+---+----+----+----+---+---+----+  
 201   202  203 204 205 206  207   208 209 210  211
  ^           ^ 
   |          |
 &val         (&val + 1) 
              its not defined.   

@CarlNorumが提案したようなtyoecaseを使用できます。私はこれを行うために2番目のフォームを書いています。

char *ptr = (char*)&val;

ptr[0]=data.front()
ptr[1]=data.front()

ただし、必要に応じvalて短く、個々のバイトにアクセスしたい場合。私は提案したいunion

union Data{
 short val;
 char ch1;
 char ch2;
};

union Data d; 

d.ch1 = data.front()
d.ch2 = data.front()
于 2013-03-01T23:08:36.437 に答える
1

ポインタをchar*にキャストする必要があります。

((char *)(&val))[1]=data.front();
((char *)(&val))[0]=data.front();

私はあなたの場合だと思います:(&val)[1] = data.front(); 2番目のshortにデータを書き込みます。その結果、エラーが発生します。

于 2013-03-01T23:11:34.103 に答える
0

(&val)[1]割り当てていないメモリにアクセスします。Bam-未定義の動作。どちらの例にも同じ問題があります。

このようにバイトを分割する場合は、charポインタを使用して個々のバイトにアクセスする必要があります。

short readshort() {
    short val=0;
    ((char *)&val)[1]=data.front(); data.pop_front();
    ((char *)&val)[0]=data.front(); data.pop_front();
    return val;
}

ただし、このコードはかなり醜いです。なぜだけではないのですか?

short readshort() {
    short val=0;
    val  = data.front() << 8; data.pop_front();
    val |= data.front() << 0; data.pop_front();
    return val;
}

エンディアンによっては、8との位置を入れ替える必要がある場合が0あります。

于 2013-03-01T23:07:32.400 に答える