0

現在、次のようにパケットをセットアップしています。

struct Packet {
    unsigned short sequenceNumber;
    unsigned short length;
    unsigned char control;
    unsigned char ack;
    unsigned short crc;
    unsigned char data[];
    Packet copy(const Packet& aPacket) {
        sequenceNumber = aPacket.sequenceNumber;
        length = aPacket.length;
        control= aPacket.control;
        ack = aPacket.ack;
        crc = aPacket.crc;
        memcpy (data, aPacket.data, aPacket.length);
    }
};

このパケットは暗号化のために文字列に変換され、復号化された文字列形式からパケットに戻す必要があります。を除くすべての変数に対してこれをうまく行うことができますunsigned char data[]。次のことを試しましたが、成功しませんでした:

string data = thePack.substr(pos, thePack.length()-pos);
    unsigned char * cData = new unsigned char[data.length()];
    strcpy((char *)cData, data.c_str());
    memcpy(p.data, cData, data.length());

ここで、data は にコピーされるデータの文字列表現でありunsigned char []、p はパケットです。

これにより、valgrind から次の結果が得られます。

==16851== Invalid write of size 1

==16851==    at 0x4A082E7: strcpy (mc_replace_strmem.c:303)

ソースとして引用していますが、コメントアウトされstrcpyた行だけでコンパイルおよび実行されます。memcpy

私も同じ結果で置き換えmemcpyてみました。strcpy何か案は?データが初期化されておらず、そこにメモリが割り当てられていない可能性があるためだと思いますが、これを処理すると思いmemcpyました。

4

2 に答える 2

3

data配列のサイズを指定していません。

unsigned char data[];

これは合法ですが、使用するのはかなり困難です。data配列はメモリ内の残りの構造に従いますが、コンパイラは配列Packetに割り当てる領域を知りません。したがって、余分なスペースを自分で割り当てる必要があります。

size_t datalen = thePack.length()-pos;
void* pbuffer = malloc( sizeof (Packet) + datalen + 1 );
Packet* p = new (pbuffer) Packet;
memcpy(p.data, &thePack[pos], datalen);
p.data[datelen] = 0;

うまくいかないのは、またはローカル変数Packetを使用して、コンパイラに a の大きさを決定させることです。それは、のために予約されたスペースがなくなるでしょう。いいえ、メモリを割り当てません。new PacketPacket p;datamemcpy

よりクリーンなソリューションはstd::vector、可変サイズのデータ​​配列に a を使用することです。

于 2011-04-27T04:23:36.460 に答える
1

char[]割り当てている文字が 1 文字小さすぎます。最後に NULL バイトの余地を残す必要があります。

unsigned char * cData = new unsigned char[data.length() + 1];

バージョンを使用しstrcpyて文字列をコピーすると、NULL バイトが正しくコピーされます。その +1 がなくても問題なく動作する可能性がありますが、保証はなく、クラッシュすることもあります。

于 2011-04-27T04:07:48.907 に答える