• ベストアンサー

C言語である関数への同時アクセスについて

たとえば int function() {   int value = rand(); //ランダムな数を取得   for ( int i = 0; i < 100000; i++ ) //数百ミリ秒くらい待機     ;   return value; } こんな関数を作成します。 これをマルチスレッドで同時に動かすとします。 例えばAというスレッドとBという2つのスレッドで同時に function()を呼び出すとします。 この場合Aというスレッドを呼び出してvalueに100が代入されたとして、 その後forループで待機している間に スレッドBからもfunction()が呼び出されvalueに200が代入されたとしたら、 スレッドAもスレッドBもfunctionの返す値はどっちも200になってしまうのでしょうか? 環境はWindowsXPでコンパイラはVisual Studio2005または2008を想定していますが、 一般的なCやC++の仕様ではこの場合の挙動はどうなるのでしょう?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

ローカル変数は呼び出しごとに異なる領域が割り当てられます。 だから大丈夫。再帰関数が定義できるのも同じ理由です。

RockmanX
質問者

お礼

そうだったんですね。 今まで同じ領域を使うんじゃないかと心配して気が気ではありませんでした。 回答ありがとうございます!

その他の回答 (1)

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

ローカル変数は、スタック上に取られます。 スタックは呼び出されるたびに新しい場所を確保する(厳密には違いますが)ので心配要りません。特に別のスレッド同士が同じスタックを使うことは絶対ありませんので安心してください。 ただし、グローバル変数だと心配されている通りの事がおきます。

RockmanX
質問者

お礼

グローバルやstaticだと同じ領域を使用してしまうんですね。 今度から気をつけることにします。ありがとうございました!

関連するQ&A

  • C言語 関数の作り方

    1~30の数字を使い、直角三角形が成り立つ組み合わせを見つけよ。(a<=b<=c) ただし、a,b,c辺を見つけて配列に入れる機能は関数にすること。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー #include <stdio.h> int main(void) {    int a,b,c,i=0,ct=0;    int ahen[20];    int bhen[20];    int chen[20];    for(a=1;a<31;a++)    {     for(b=1;b<31;b++)     {      for(c=1;c<31;c++)      {       if(a*a+b*b==c*c && a<=b && b<=c)       {         ahen[i]=a;         bhen[i]=b;         chen[i]=c;         i=i+1;         ct++;       }      }     }    }    for(i=0;i<ct;i++)    {     printf("%d %d %d\n",ahen[i],bhen[i],chen[i]);    }    return 0; } 実行例: 3 4 5 5 12 13 6 8 10 7 24 25 8 15 17 9 12 15 10 24 26 12 16 20 15 20 25 18 24 30 20 21 29 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー とりあえず、関数を使わない上記のプログラムを作って見ました。 ここから関数を使ったものに変更したいのですが、配列が絡むとさっぱり分かりません。 printfで表示する箇所以外を全て関数にするのだと思いますが、どなたかご教示願います。

  • C言語の代入についての質問です

    C言語の代入についての質問です 下のプログラムを見て下さい #include<stdio.h> int x[2]; x[0] = x[1] = 1; int main(void) { for(int i = 0 ; i < 2 ; i++) printf("%d",x[i]); putchar('\n'); return 0 ; } このプログラムをコンパイラすると3行目の代入にエラーが出されます (当たり前ですがmainの中に3行目の代入文を入れると上手くいきます) まぁそれがなぜかというのが知りたいのですが、 それはC言語をつくった人が決めたことなのでしょうか? ちなみに異なる実行環境でやってみたらどれも駄目だったので これが上手くいくことはない?のだと思います そういうもんなのだったら、そういうものだと理解しますが もし理由を知っている方がいらっしゃったら教えて下さい

  • C言語、関数、ポインタ、エラー見つけられません。

    いつも大変お世話になり誠にありがとうございます。 標記の件。 エラーが見つけられません。 どうかアドバイスをください。       記 コード #include <stdio.h> double avg(int *pT); int main(void) { int rest[5]; int i; double ans; printf("5人のテストの点数を入力してください。\n"); for(i=0; i<5; i++){ scanf("%d", &test[i]); } ans = avg(test); printf("5人の平均点は%lf点です。\n", ans); return 0; } /*avg関数の定義*/ double avg(int *pT) { int i; double sum; sum = 0.0; for(i=0; i<5; i++){ sum += pT[i]; } return sum/5; } コンパイラーエラー C:\MinGW>gcc text19.c -o text19 text19.c: In function 'main': text19.c:14:22: error: 'test' undeclared (first use in this function) scanf("%d",&test[i]); ^~~~ text19.c:14:22: note: each undeclared identifier is reported only once for each function it appears in 14行目にエラーがあるのかな?と思いますが 間違っていないようです。 ご多忙中恐れ入ります。 ご回答の程宜しくお願い申し上げます。

  • C言語プログラミングについて

    皆さんのお力をお貸しください 問題 1~20番のナンバーの車が200週の耐久レースをする。ENTERKEYを押すたびにコースを一周するものとし、一周するごとに20台のうち一台がランダムに選ばれ、選ばれた車は1~6のランダムに選ばれた数字の数だけ順位を上げるプログラムをかいてください。 ※ただしグローバル変数、ポインタは使わずif,for,while,配列のみで書くこと。 実行結果は #(選ばれた車のナンバー)   over(抜いた台数) 現在の周回数( ) 順位 1   (車のナンバー)     2   (車のナンバー)     3   (車のナンバー)        ・        ・          ・                    ()の中身はenterを押すたびに変化する となるようにしてください ポインタありのサンプルプログラムは組めたのですが、※の条件が付けられて、戸惑っています。 恥を忍んで皆さんにお願い申し上げます。 以下、サンプル(インデントの狂いやコメントに関してはご容赦ください) #include <stdio.h> #include <stdlib.h> #include <time.h> #define my_rand(n) (int)((n) * (rand() / (RAND_MAX + 1.0))) void swap(int *a, int *b) { int c = *a; *a = *b; *b = c; } void up_rank(int a[], int m, int n) { while(n --){ if(!m --) break; swap(&a[m], &a[m + 1]); } } void print(int car[], int n) { int i; int j = 0; for(i = 0; i < n; ++ i) { j++; printf("[%2d] %d\n",j, car[i]); } /*putchar('\n');*/ } int main(void) { int car[] = {95,43,86,8,52,28,64,58,76,70,4,34,63,92,35,33,56,80,54,74},i;               //各車のナンバー。皆さんは1~20でかまいません srand((unsigned)time(NULL)); printf("Start\n"); print(car, 20); system("pause"); system("cls"); for(i = 0; i < 201; ++ i) { int c, m = my_rand(20), n = my_rand(6) + 1; if(i<200) { printf("#%d, Overtake +%d\n",car[m] , n); printf("raps = %d\n",i+1); } else { printf("Finishing Positions\n"); } up_rank(car, m, n); print(car, 20); system("pause"); system("cls"); } return 0; }

  • C言語の関数を読み込みません。

    今、ゲームのようなプログラムを作っていて、下はそのダメージ計算量を計算するプログラムを書いたつもりでいたのですが、どうやら「compatibility」と作った関数が計算されていないようです。 int compatibility(int a[2][3], int s, int t, struct monster monster[]) { int m; int add; printf("a2\n"); if( (monster[a[s][0]-1].tricktype == 1 && (monster[a[t][0]-1].type == 3 || monster[a[t][0]-1].type == 4)) || (monster[a[s][0]-1].tricktype == 2 && monster[a[t][0]-1].type == 1) || (monster[a[s][0]-1].tricktype == 3 && (monster[a[t][0]-1].type == 2 || monster[a[t][0]-1].type == 4)) || (monster[a[s][0]-1].tricktype == 4 && (monster[a[t][0]-1].type == 2 || monster[a[t][0]-1].type == 5)) || (monster[a[s][0]-1].tricktype == 5 && (monster[a[t][0]-1].type == 1 || monster[a[t][0]-1].type == 3)) /* 効果抜群 */ ){ m = (int)rand() % 2; if(m == 0) add = 1; if(m == 1) add = 2; }else{ if( (monster[a[s][0]-1].tricktype == 1 && (monster[a[t][0]-1].type == 2 || monster[a[t][0]-1].type == 5)) || (monster[a[s][0]-1].tricktype == 2 && monster[a[t][0]-1].type == 3) || (monster[a[s][0]-1].tricktype == 3 && (monster[a[t][0]-1].type == 1 || monster[a[t][0]-1].type == 5)) || (monster[a[s][0]-1].tricktype == 4 && (monster[a[t][0]-1].type == 1 || monster[a[t][0]-1].type == 3)) || (monster[a[s][0]-1].tricktype == 5 && monster[a[t][0]-1].type == 4 ) /* 効果いまひとつ */ ){ m = (int)rand() % 2; if(m == 0) add = 1; if(m == 1) add = 1/2; }else{ m = (int)rand() % 10; if(m == 0){ add = 2; }else{ if(m == 15){ add = 1/2; }else{ add = 1; } } } } return add; } int damage(int i, int a[2][3], struct monster monster[], int b[2]) { int add; double damage; int s, t, u; s = (i+1) % 2; t = i % 2; u = (int)rand() % 32; add = compatibility(a, s, t, monster); ・ ・ ・ } printf("a2\n");を関数内に用いて、実際にcompatibility関数を読み込んでいるのか確かめたのですが、コンパイラーにそう表示されることなく、関数を読み込んでいないのではと判断したしだいです。 長文すいません、お手数ですがどこをどのように変更すればいいのか、教えていただけるとありがたいです。 よろしくお願いします。 ちなみにa[2][3]はint型の配列、monsterはint型のtypeやtrickeffectを収入したもののつもりです。

  • C言語に直して下さい

    VisualC++で円周率を求めるプログラムなのだそうですが、 自分はC言語しか使ったことがないため、よく分かりません。 Cでコンパイルできるように直していただけないでしょうか。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 21 #define K 100000 void add(unsigned long a[],unsigned long b[]) { int c = 0, tmp; for (int i = N - 1; i > -1; i--) { tmp = a[i] + b[i] + c; a[i] = tmp % K; c = tmp / K; } } void sub(unsigned long a[],unsigned long b[]) { int c = 0, x = 0; for (int i = N - 1; i > -1 ; i--) { x = c; if (a[i] < b[i] + x ) c = 1; else c = 0; a[i] = c * K + a[i] - b[i] - x; } } void div(unsigned long a[], unsigned long x) { int c=0, tmp; if (x >= K) { printf("Div Error\n"); getchar(); exit(1); return; } for (int i = 0; i < N ; i++) { tmp = (a[i] + c * K) / x; c = (a[i] + c * K) % x; a[i] = tmp; } } void clear(unsigned long a[]) { memset(a,0x00,sizeof(a)*N); } void set(unsigned long a[], unsigned long b[]) { memcpy(a,b,sizeof(a)*N); } void set(unsigned long a[], unsigned long b) { if (b<K) { clear(a); a[0]=b; } } int _tmain(int argc, _TCHAR* argv[]) { unsigned long pai[N], fn[N], gn[N], tmp1[N], tmp2[N]; int i; unsigned long n; clear(pai); clear(fn); clear(gn); clear(tmp1); clear(tmp2); set(fn, 16*5); set(gn, 4*239); for(n=0;n<40000;n++) { div(fn, 25); div(gn, 239); div(gn, 239); set(tmp1, fn); div(tmp1, 2*n+1); set(tmp2, gn); div(tmp2, 2*n+1); if (n%2==0) { add(pai, tmp1); sub(pai, tmp2); }else{ add(pai, tmp2); sub(pai, tmp1); } } for (i=0;i<N;i++) { printf("%5lu ", pai[i]); } getchar(); return 0; }

  • C言語をお願いします

    普通には出来たのですが、配列や関数の使い方がよく分かりません。 助けてください。よろしくお願いします。 問 1~30の整数の範囲で、3辺a, b, c(cを斜辺)の三角形のうち、直角三角形が成立する場合を見つけて配列に入れる。その後、配列をもとにプログラムを作成。 ※a, b, c辺を見つけて配列に入れる機能は関数にすること。 ※a <= b、b <= cを仮定。 #include<stdio.h> int myfunc(int x, int y, int z); int main(){ int a, b, c; for(a=1; a<=30; a++){ for(b=a; b<=30; b++){ for(c=b; c<=30; c++){ if(a*a + b*b == c*c){ printf("%d,%d,%d",a,b,c); puts(" "); } } } } return 0; } 実行例 3,4,5 5,12,13 ・ ・ よろしくお願いします。

  • 複素数代入解(C言語)

    n次の実多項式に複素数を代入するプログラムを教えてください。 typedef struct{ double r; double i; }comp; /*複素数の和*/ comp c_add(comp a,comp b){ comp c; c.r = a.r + b.r; c.i = a.i + b.i; return(c); } /*複素数のべき乗*/ comp c_pow(comp a,int n){ comp c; int i; double tpr,tpi; c.r = a.r; c.i = a.i; for(i=1;i<n;i++){ tpr = c.r; tpi = c.i; c.r = tpr*a.r - tpi*a.i; c.i = tpr*a.i + tpi*a.r; } return(c); } を定義してから、 /*a[]は多項式の係数、nは多項式の次数、bは代入する複素数*/ comp c_poly_eval(double a[], int n, comp b){ int i; comp tmp={0.0,0.0}; for(i=n; i>=0; i--){ tmp = c_add(tmp, a[i]*c_pow(b,i)); } return(tmp); } を作ったのですがエラーが出てしまいます。 a[i]*c_pow(b,i)でn次の値を計算して、c_addにいれることで0次~n次までの和を求めようとしたのですが、何が違うのでしょうか?

  • c言語で分からないところがあるので教えてください。

    http://www9.plala.or.jp/sgwr-t/c/Q/ens06-61.html の問題がわかりません。 回答の #include <stdio.h> int main( void ) { int kekka[51]; int a, b, i; int amari; printf( "整数値を2つ入力してください " ); scanf( "%d%d", &a, &b ); if( b == 0 ){ printf( "処理終了\n" ); return 0; } printf( "%d / %d = ", a, b ); kekka[0] = a/b; for ( i = 1; i < 51;i++ ) { amari = a%b; if ( amari == 0 ) break; a = amari * 10; kekka[i] = a/b; } printf( "%d.", kekka[0] ); ここまでの部分はわかったのですが、 下の for ( a = 1; a < i; a++ ) { printf( "%d", kekka[a] ); } の部分がわかりません。 この部分は何を表わしているのか 教えてください。

  • c言語について

    #include <stdio.h> MakeData(int *a,int n){ int i,b[5]={5,1,4,7,2}; for(i=0;i<5;i++){a[i]=b[i];} } BubbleSort(int n,int *a){ ここに流れ図に沿ったプログラムを作る } main(){ int i,n,a[100]; n=5; MakeData(a,n); for(i=0;i<n;i++){printf("%4d ",a[i]);}printf("¥n"); printf("並べ替え後¥n"); BubbleSort(n,a); for(i=0;i<n;i++){printf("%4d ",a[i]);}printf("¥n"); } この課題が分かりません。 もし詳しい方がいらっしゃいましたら教えて頂けると助かります。

専門家に質問してみよう