実際のプログラムでバグが出たので、簡易化したプログラムでテストしてみましたがどこが悪いのか分かりませんでした。
#include <WinSock2.h>
#include <vector>
#include <process.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
CRITICAL_SECTION cs;
unsigned __stdcall Login( void * );
int main()
{
vector<unsigned int> thID;
vector<HANDLE> hTh;
for( int i=0 ; i<10 ; i++ )
{
printf( "メインスレッド:%d\n", i );
if( (i%2) == 0 )
{
thID.push_back( i );
hTh.push_back( (HANDLE)_beginthreadex(NULL, 0, Login, &i, 0, &thID[i]) );
}
}
while(1)
{
for( int i=0 ; i<10 ; i++ )
{
if( hTh[i] != NULL )
{
CloseHandle(hTh[i]);
}
}
char a[2];
scanf( "%c", a );
if( strcmp( a, "X" ) == 0 )
{
return 0;
}
}
}
unsigned __stdcall Login( void *Num )
{
int *a = (int *)Num;
for( int i=0 ; i<10 ; i++ )
{
printf( "サブスレッド%d:%d\n", *a, i );
}
return 0;
}
出るエラーは以下のようになります
Windows によって Server.exe でブレークポイントが発生しました。
ヒープが壊れていることが原因として考えられます。Server.exe または読み込まれた DLL にバグがあります。
あるいは、Server.exe がフォーカスを持っているときに、ユーザーが F12 キーを押したことが原因として考えられます。
可能であれば、出力ウィンドウに詳細な診断情報が表示されます。
if( (i%2) == 0 )
をコメントアウトするとエラーは出ません
また、共に
表示される例として(見やすいように空行あり)
以下のように、
スレッド番号が+1されていたり(A)
各スレッド内のループ回数が直前のスレッドの回数を引き継いでいたり(B)
スレッドのループ回数が初期化されていたり(C)
呼び出されてないはずのスレッドが起動していたり(D)
します
メインスレッド:0
メインスレッド:1
サブスレッド1:0 ・・・・・・A(本来はサブスレッド0のはず)
サブスレッド1:1
メインスレッド:2
サブスレッド2:3 ・・・・・・B(本来はサブスレッド2:0のはず)
サブスレッド2:4
サブスレッド2:5
サブスレッド1:0 ・・・・・・C(本来は1:3のはず)
サブスレッド1:1
サブスレッド2:0
サブスレッド3:0 ・・・・・・D(本来はまだ起動してないはず)
サブスレッド3:1
メインスレッド:3
どこを直せばいいか教えてください
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
> では、どのようにしたらいいのでしょうか?
たとえばこんな:
#include <WinSock2.h>
#include <vector>
#include <tuple>
#include <process.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
CRITICAL_SECTION cs;
unsigned __stdcall Login( void * );
int main() {
typedef tuple<unsigned int, HANDLE, int> record;
vector<record> records;
for( int i=0 ; i<10 ; i++ ) {
printf( "メインスレッド:%d\n", i );
if ( (i%2) == 0 ) {
records.push_back(record());
record& r = records.back();
get<2>(r) = i;
get<1>(r) = (HANDLE)_beginthreadex(NULL, 0, Login, &get<2>(r), 0, &get<0>(r) );
}
}
...
わざわざありがとうございます。
tupleという物があるんですね。
知らなかったです
調べてみましたが、どういうものかは分かりましたがプログラムで何をしているのか分からなかったのでそのままコピペしてみました
結果
メインスレッド:0~9
サブスレッド-17891602:0~9
サブスレッド0:0~9
サブスレッド-17891602:0~9
サブスレッド-17891602:0~9
サブスレッド8:0~9
となりました
大体道筋が見えてきたように思います。
No.3
- 回答日時:
今現在の問題のあるコードと実行結果を貼って下さい。
この回答への補足
あ、申し訳ありません
前略
{
vector<unsigned int> thID;
vector<HANDLE> hTh;
DWORD dwExCode;
for( int i=0 ; i<10 ; i++ )
{
printf( "\nメインスレッド:%d\n", i );
if( (i%2) == 0 )
{
thID.push_back( i );
hTh.push_back( (HANDLE)_beginthreadex(NULL, 0, Login, &i, 0, &thID[i/2]) );
}
}
while(1)
{
for( int i=0 ; i<hTh.size() ; i++ )
{
GetExitCodeThread(hTh[i], &dwExCode);
if( dwExCode != STILL_ACTIVE )
{
CloseHandle( hTh[i] );
vector<HANDLE>::iterator end_it = remove( hTh.begin(), hTh.end(), HANDLE(hTh[i]) );
hTh.erase( end_it, hTh.end() );
vector<unsigned int>::iterator End_it = remove( thID.begin(), thID.end(), unsigned int(thID[i]) );
thID.erase( End_it, thID.end() );
}
}
char a[2];
scanf( "%c", a );
if( strcmp( a, "X" ) == 0 )
{
return 0;
}
}
}
以下略
結果の一例
M:0
M:1
M:2
S2:0
S3:1~9
M:3
M:4
S3:0
S4:1
S5:2~9
M:5
M:6
S5:0
S7:1
M:7
M:8
S7:2
S9:3~9
No.2
- 回答日時:
怪しい所です。
1.スレッドに変数寿命が切れたローカル変数iを渡している。
2.vectorでpush_backした要素数よりも多い番号を参照。
(i%2) == 0 )で2回に一回しかpush_backしないのに&thID[i]でi番目を参照しています。
3.以下の部分は10個要素がある前提に成っているが10個無いのでエラーです。
for( int i=0 ; i<10 ; i++ )
{
if( hTh[i] != NULL )
{
CloseHandle(hTh[i]);
}
}
4.スレッドの終了を待たずにCloseHandleしている。
1.はepistemeさんと同じことですよね?
2.3.あ、本当ですね。だから偶数のときにスレッドを立てるようにしたらエラーになったんですね
4.そこは盲点でした。
とりあえず、2.3.4.を直してこようと思います
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「指定されたキャストは有効で...
-
比較回数と交換回数表示について
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
#define _CRT_SECURE_NO_WARNIN...
-
std::set<int> で、ある値が何...
-
C言語で三目並べをするプログラ...
-
商と剰余を同時に求める(C言語)
-
if と配列の組み合わせ
-
【C++】関数ポインタの使い方
-
並列プログラミングのπ計算につ...
-
c言語
-
HANDLEて何ですか?
-
read関数をノンブロッキングで...
-
卒業研究でよく分からないとこ...
-
DLLをGetProcAddress()で実行で...
-
GlobalAllocの変数を関数に引き...
-
シグマ公式・・・C言語
-
ファイルから読みこむ方法
-
c言語の問題です
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
「指定されたキャストは有効で...
-
C言語 配列と関数の練習問題
-
複数桁10進数の*桁目だけを抽出...
-
(int *)の意味
-
if と配列の組み合わせ
-
ラップ関数とはどんなものですか?
-
卒業研究でよく分からないとこ...
-
【C++】関数ポインタの使い方
-
c言語
-
足して100になるような乱数のア...
-
C言語初心者です、、、お助けく...
-
数字列を3桁ごとにカンマで区切...
-
C言語 エラーの原因がわからな...
-
実数の整数部,小数部の取得
-
課題でつまってます・・・
-
商と剰余を同時に求める(C言語)
-
C言語の配列をC++のvectorに高...
-
std::set<int> で、ある値が何...
おすすめ情報