2017-04-20 26 views
0
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <string.h> 
#include <strings.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <pthread.h> 


typedef struct client{ 
int threadid; 
int argc; 
char *argv[3]; 
}client; 

void exit(int status); 
void error(char *msg); 

void *threadClient(void *socket_desc); 

int main(int argc, char *argv[]){ 
    client info[10]; 
    pthread_t thread[10]; 

    printf("%s\n%s\n%s\n", argv[0], argv[1], argv[2]); 

    // Error happens here 

    for (int i=0; i<=10; i++){ 
    info[i].threadid = i; 
    strcpy(info[i].argv[0], argv[0]); 
    strcpy(info[i].argv[1], argv[1]); 
    strcpy(info[i].argv[2], argv[2]); 
    info[i].argc = argc; 
    printf("here"); 
     if(pthread_create(&thread[i] , NULL , threadClient , (void*)&info[i]) < 0){ 
      perror("could not create thread"); 
      return 1; 
     } 
     sleep(3); 
    } 
    pthread_exit(NULL); 
    return 0; 

} 

ループ中に、argvの情報を私の構造体にコピーしようとすると、セグメント化エラーが発生します。それはなぜ起こるのですか?strcpy()上のセグメンテーションフォルト。

プログラム受信信号SIGSEGV、セグメンテーションフォルト。 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296 の__strcpy_sse2_unaligned()296 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:このようなファイルまたはディレクトリはありません。

+1

1) '私<=10' -->'私は<10 '2) 'strcpyの(情報[i]が.argv [0]、ARGV [0]);' 'info [i]。argv [0] 'は初期化されません。 – BLUEPIXY

+0

私はforループの問題を変更しました。私はそこに置いたことに気付かなかったことに感謝します。しかし、私はそれをどのように初期化するつもりですか? – jhowe

+0

'info [i] .argv [0] = malloc(strlen(argv [0])+ 1);' 'strcpy'の前。 – BLUEPIXY

答えて

1

ここには2つの問題があります。

最初に、info構造のargv配列はポインタの配列です。これらは初期化されていません。後でstrcpyを呼び出すと、これらの配列要素の1つを最初のパラメータとして指定すると、そのポインタが有効なメモリを指していると想定します。つまり、初期化されていないポインタの参照を解除します。これにより、undefined behaviorが呼び出されます。この場合、segfaultとして表示されます。

これらのポインタに何かを割り当てる必要があります。あなたはこれらの文字列のコピーを作成するstrdupを使用することができ、次のいずれか

info[i].argv[0] = strdup(argv[0]); 
info[i].argv[1] = strdup(argv[1]); 
info[i].argv[2] = strdup(argv[2]); 

それとも、あなたはこれらの値を変更する予定がない場合は、あなただけの直接ポインタ値をコピーすることができます。

info[i].argv[0] = argv[0]; 
info[i].argv[1] = argv[1]; 
info[i].argv[2] = argv[2]; 

あなたが<=を使用するので、配列へのあなたのインデックスがしかし、0から10までの範囲で、あなたの配列が唯一の10を持っている

for (int i=0; i<=10; i++){ 

:第二の問題は、あなたのループにおけるoff-by-oneエラーです要素(インデックス0から9まで)を使用しているため、配列の最後を超えて記述しています。これは未定義の動作も引き起こします。

変更は<にあなたの条件を次のように

for (int i=0; i<10; i++){ 
0

あなたの構造体は、3つのポインタ(char *argv[3])を含むように定義されています。これらの構造体の配列をスタック(client info[10])に作成すると、これらのポインタのための領域が確保されます。構造体は何にも初期化されていないので、ポインターは賢明なメモリー位置を指しません。したがって、strcpy(info[i].argv[0], argv[0]);のようにアクセスするとエラーになります。

のどちらかを明示的に使用スペースの割り当て:

info[i].argv[0] = malloc(strlen(argv[0])+1); 
strcpy(info[i].argv[0], argv[0]); 

をや文字列をコピーするstrdup()を使用します。

info[i].argv[0] = strdup(argv[0]); 

free()にあなたが後で割り当てられたスペースを覚えておいてください。


また、私はそれが標準機能だとstdlib.hにする必要があり、あなたがexit()と呼ばれる関数を自分で宣言する必要はないと思います。

関連する問題