2

このコードを実行すると、「セグメンテーション エラー (コア ダンプ)」が表示されます。

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

void function(char *oz){

    char *y;
    y = (char*)oz;
    **y="asd";


    return NULL;
}

int main(){
    char *oz="oz\n";

    pthread_t thread1;

    if(pthread_create(&thread1,NULL,function,(void *)oz)){
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }

    if(pthread_join(thread1,NULL)){
        fprintf(stderr, "Error joining thread\n");
        return 2;
    }
    printf("%s",oz);
    return 0;

}
4

2 に答える 2

2

コンパイラは、これらの問題のいくつかについて警告している可能性があります。コンパイラの警告を無視しないでください! 警告は、コンパイラが「待ってください! このコードのビットをよく理解していません... 私が理解できる言語で記述してください! 」と伝える方法です。あなたはどの本を読んでいますか。このアプローチから発生する、この質問では言及しない他の問題があります。「試行錯誤」や「見当違いの例」 (コピー/貼り付けや変更など) によって C を学ぶのは安全ではありません。あなたは、生計を立てるためにプログラミングを教えている教授によって書かれた本を読んでいるはずです。これ以上読む前に、この質問に答えてください。

pthread_create次のようなシグネチャを持つ関数を示す関数ポインタが必要です。

void *function(void *argument);

与えている関数ポインターは、その署名を前提とする関数ポインターに変換されます。pthread_create次に、その関数ポインタを使用しようとしますが、方法を知っている唯一の方法です...これは未定義の動作です。...さらに、@AdamRosenfield で示されているように、を返す関数から値を返すことはできませんvoid。これにより、コンパイラがエラーと警告を吐き出すはずです。関数は次のようになります。

void *function(void *oz) {
    /* ... */
}

ブロックコメントには、質問の別の一連の嘘があります。コードはコンパイルされないため、segfault は発生しません。yis a char *... *yis a char...**yはコンパイラ エラーです。一度だけ逆参照するつもりだったと思いますが、 a に代入"asd"してcharも意味がないので、yas として宣言するつもりだったと仮定する必要がありますchar **y;。タイプキャストを不必要に使用しているようです。それらを使用する前にそれらについて学び、それらを誤用したり、必要のない場所で使用したりしないようにします (achar *を aに変換しようとするなどchar *)。

void *function(void *oz) {
    char **y = oz;
    *y = "asd";
}

char **したがって、おそらく pthread_open にも値を渡す必要があります。値を渡して、それが値でchar *あるかのように扱うのは意味がありませんchar **よね? オブジェクトへのポインターをvoid *;にキャストする必要はありません。その変換は、自動変換の 1 つです。

if (pthread_create(&thread1, NULL, function, &oz)){
    fprintf(stderr, "Error creating thread\n");
    return 1;
}
于 2013-05-01T15:08:40.747 に答える