0

2つの整数と1つの文字列をバッファにコピーして、バッファ要素を出力しようとしています。3番目のprintfステートメントでセグメンテーション違反が発生しました。

    id = 102;
    len = 3;
    str = "working";
    memmove(buffer,&message_id,sizeof(id));
    memmove(buffer+(sizeof(id)),&len,sizeof(len));
    memmove(buffer+(2*sizeof(id)),&string, sizeof(str));

    printf("1 is: %d\n", buffer[0]);
    printf("2 is: %d\n", buffer[4]);
    printf("3 is %s\n, buffer[8])); // here is where i get the seg fault should
    be a string
    /***/
    bufer is declared as unsinged char buffer[444];

なぜこれがセグメンテーション違反になるのかわかりませんか?

4

3 に答える 3

4

buffer[8]は、char文字%s列を待機します。つまりchar *、代わりに渡し&buffer[8]ます。printfがcharをアドレスであるcharへのポインタとして処理しようとするため、セグメンテーション違反が発生します(charが渡された場合、有効なものになる可能性は低くなります)

編集:Davidがコメントしたように、文字列をコピーするための開始点がその前の値に関連している場合は、使用する代わりに固定値を使用しないで&buffer[8]くださいbuffer+(2*sizeof(id))buffer[2*sizeof(id)]

于 2011-04-28T00:22:51.290 に答える
1

主な問題は、文字のみを渡して文字列を印刷しようとしていることです。これは、インデックス8をbuffer[8]参照しているためであり、その位置から始まる文字列ではありません。charしたがって、のアドレスをbuffer[8]取得して文字列またはにする必要がありますchar*

segfaultsが発生する理由はprintf、最初の文字で指定されたアドレス(つまり、文字列の内容自体)から始まる文字列を出力しようとするためです。これは、有効なポインタではありません。

タイプミスや間違いもたくさんあります。動作するバージョンは以下のとおりです。

#include <stdio.h>
#include <memory.h>

int main()
{
    unsigned char buffer[444];
    int id = 102;
    int len = 3;
    char* str = "working";

    memmove(buffer,&id,sizeof(id));
    memmove(buffer+(sizeof(id)),&len,sizeof(len));
    memmove(buffer+(2*sizeof(id)), str, sizeof(str));

    printf("1 is: %d\n", buffer[0]);
    printf("2 is: %d\n", buffer[4]);
    printf("3 is %s\n", &buffer[8]);

    return 0;
}

すべての警告を有効にしてこのアプリをコンパイルした場合(つまり-Wall、)、コンパイラ(少なくともGCCは有効)は、次のような間違いについて警告する必要があります。

problem.c:18: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’

警告は無視しないでください!

于 2011-04-28T00:46:18.233 に答える
1

コードにはいくつかの問題がありましたが、最も重要な点はmemmove()、文字列のヌル文字バイトをコピーしないことです。

この関数は、ソース内の終了ヌル文字をチェックしません。常に正確にnumバイトをコピーします。

これにより、2つのオプションが提供されます。

  • あなたがものをコピーしている間、それを説明してください:

memmove(buffer+sizeof(id)+sizeof(len), str, strlen(str) +1);

  • '\0'または、メモリがコピーされた後、文字列がバッファの(aka。 )で終わっていることを確認し0てください。

memmove(buffer+sizeof(id)+sizeof(len), str, strlen(str));

buffer[sizeof(id)+ sizeof(len) + strlen(str) + 1] = 0;

とにかく、コードは今動作します。もう1つの問題は、文字列の長さを。で指定しようとしたことですsizeof(str)。それは間違っています、そしてあなたはやるべきですstrlen(str)。最後にもう1つ、明確さとセキュリティの目的で、そうしないでください2*sizeof(id)。後で可変タイプを変更することにした場合、あなたは失敗します。正しい方法がありますsizeof(id)+sizeof(len)。それで全部です。

int id = 102;
int len = 3;
char* str = "working";
char buffer[444];

memmove(buffer,&id,sizeof(id));
memmove(buffer+(sizeof(id)), &len, sizeof(len));
memmove(buffer+sizeof(id)+sizeof(len), str, strlen(str));
buffer[sizeof(id)+ sizeof(len) + strlen(str) + 1] = 0;

printf("1 is: %d\n", buffer[0]);
printf("2 is: %d\n", buffer[4]);
printf("3 is: %s\n", &buffer[8]);
于 2011-04-28T00:52:46.923 に答える