0

私はここで何が間違っているのだろうか?void ポインターを構造体バッファーにキャストすると、ガベージのみが出力されます。buffer は、メモリを割り当てた元のバッファへのポインタである ptr を指すべきではありませんか?

#include <stdio.h>
#include <pthread.h>

 struct buffer{
         int a;
         char *string[];
 }buffer;

 void thread1_function(void *ptr){
         struct buffer *buffer=(struct buffer*)ptr;

         printf("hello world\n");

         printf("%s-%n\n", buffer->string,buffer->a);

 }

 int main(){

        struct buffer *buffer;
        int err;
        buffer = (struct buffer*)malloc((11*sizeof(char))+sizeof(int));
        pthread_t thread1;
        sprintf(buffer->string,"%s","strint");
        buffer->a=1;
        printf("main: %s - %d\n",buffer->string,buffer->a);
        err = pthread_create(&thread1, NULL, thread1_function, &buffer);
        printf("error: %d\n",err);
        pthread_join(thread1,NULL);
        return 0;
 }

4

3 に答える 3

4

構造体のメンバーは、ポインターstringの「柔軟な」配列として定義されます。代わりに、バイトを割り当ててから文字列をコピーすることにより、文字の配列として扱うようです。char * 11 * sizeof(char)

構造の意図したレイアウトは次のようにする必要があると思います。

struct buffer {
     int a;
     char string[];
} buffer;

そして、次のように割り当てます。

buffer = malloc(sizeof(struct buffer) + SIZE_OF_STRING);
于 2012-04-04T07:12:09.857 に答える
4

構造体へのポインターへのポインターをスレッドに渡します。代わりにポインタを構造体に渡してみてください。;)

err = pthread_create(&thread1, NULL, thread1_function, &buffer);

になる

err = pthread_create(&thread1, NULL, thread1_function, buffer);

編集: 別の間違いが見つかりました:printf("...%n")スレッド関数で。%nこれまでに書き込まれた番号をその位置に格納することを示し、int*その位置のパラメーターが指します。%dのように、あなたは明らかにそこを意味しますmain()

于 2012-04-04T07:27:06.757 に答える
2

他の人がすでに提供しているメモに加えて:

  • sの境界を超えて書き込むことを確実に回避するには、 snprintfを使用する必要があります。string
  • 十分なメモリが割り当てられていることを確認するために使用するsizeof(struct buffer)(または単にstruct bufferスタック上に作成する)必要があります(パディングの問題がある可能性があります)。もちろん、文字配列とそのポインタ()にメモリを割り当て、適切に初期化する必要がある場合もありますstring
  • pthread_createのmanページを見ると、3番目の引数はむしろ&thread1_function関数ポインタである必要があります。また、の代わりにthread1_function()を返す必要があります。void*void
  • 名前には2つの変数があることに気づきましたかbuffer(1つはグローバルスコープにあり、もう1つは関数内にありますmain())。とにかく、どちらをスレッドに渡すかをどのように確認しますか?

結局のところ、そのコードには非常に多くの問題があります。1つのエラーを修正した後でも、コードが失敗するのは驚きではありません。(実際、コンパイルされたことに驚いています。)


いくつかの修正されたコードは次のとおりです。最初にコードをコンパイルするときに多くの警告がありました。警告を無視しないでください。コードがコンパイルされたとしても、警告はエラーを追跡するための貴重な情報であることが多く、特にプログラムが失敗した場合に顕著です。あなたの場合のように。そもそも、印刷されるゴミについては気にする必要はありませんが、コンパイラがあなたに投げかける警告については気にする必要があります。

(さらに警告が必要な場合は、選択したものに渡し-Wall -Wextra -pedanticてみてくださいgcc。)

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

struct buffer{
    int a;
    char string[10];
};

void* thread1_function(void *ptr){
    struct buffer *buffer=(struct buffer*)ptr;
    printf("hello world\n");
    printf("%s-%d\n", buffer->string,buffer->a);
    return NULL;
}

int main(){

    int err;
    pthread_t thread1;
    struct buffer *buffer;

    buffer = (struct buffer*)malloc(sizeof (struct buffer) );
    buffer->a=1;
    snprintf(buffer->string, sizeof buffer->string, "%s", "strint");
    printf("main: %s - %d\n", buffer->string, buffer->a);

    err = pthread_create(&thread1, NULL, &thread1_function, buffer);
    printf("error: %d\n", err);
    pthread_join(thread1, NULL);

    return 0;
}
于 2012-04-04T07:39:04.250 に答える