質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

メモリリーク

メモリリークは、プログラムファイルがメモリの解放に失敗した時に起こります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

861閲覧

ヒープに関するエラーが不規則に出現します。

takenok0

総合スコア5

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

メモリリーク

メモリリークは、プログラムファイルがメモリの解放に失敗した時に起こります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/08/21 17:02

前提・実現したいこと

プログラム初心者です。
C++とOpenAL,GLを使ってインパルスを測定するプログラムを作っています。
しかし、実行するたびにうまく起動したりしなかったりがランダムで発生しています。
どうもメモリの動的確保時にエラーが起きているようですが、それの原因がわかりません。

発生している問題・エラーメッセージ

ハンドルされない例外が 0x00007FFCFDA7B049 (ntdll.dll) で発生しました(Impalse.exe 内): 0xC0000374: ヒープは壊れています。 (パラメーター: 0x00007FFCFDAE27F0)。

該当のソースコード

関係のないところは省略しました。

C++

1#define _USE_MATH_DEFINES 2#define Window_Width 640 3#define Window_Height 640 4 5#include <AL/al.h> 6#include <AL/alc.h> 7#include <GL/glfw3.h> 8#include <iostream> 9#include <stdlib.h> 10#include <windows.h> 11#include <math.h> 12 13#ifdef _MSC_VER 14#define strdup(x) _strdup(x) 15#endif 16using namespace std; 17#pragma comment(lib, "AL/OpenAL32.lib") 18#pragma comment(lib, "GL/OpenGL32.lib") 19#pragma comment(lib, "GL/glfw3.lib") 20#pragma comment(lib, "GL/glfw3dll.lib") 21 22#define SAMPLING_RATE 48000 23#define BUFFER_SIZE 1024 24#define WAV_NAME "tsp_2^15_48k.wav" 25#define S_LENGTH 32768 26#define T 3 27#pragma warning(disable:4996) 28 29char type[4]; 30DWORD parameter, chunkSize; 31short formatType, channels; 32DWORD sampleRate, avgBytesPerSec; 33short bytesPerSample, bitsPerSample; 34DWORD dataSize, WAV_LENGTH; 35 36signed short* wav_data; 37signed short* output; 38int save; 39char memory; 40int now_w = Window_Width; 41int now_h = Window_Height; 42 43 44 45int endWithError(char* msg, int error = 0) { 46 //Display error message in console 47 cout << msg << "\n"; 48 system("PAUSE"); 49 return error; 50} 51 52void fft(int n, double ar[], double ai[]) 53{ 54 int m, mh, i, j, k; 55 double wr, wi, xr, xi, theta = 2 * M_PI / S_LENGTH; 56 57 for (m = n; (mh = m >> 1) >= 1; m = mh) 58 { 59 for (i = 0; i < mh; i++) 60 { 61 wr = cos(theta * i); 62 wi = sin(theta * i); 63 for (j = i; j < n; j += m) 64 { 65 k = j + mh; 66 xr = ar[j] - ar[k]; 67 xi = ai[j] - ai[k]; 68 ar[j] += ar[k]; 69 ai[j] += ai[k]; 70 ar[k] = wr * xr - wi * xi; 71 ai[k] = wr * xi + wi * xr; 72 } 73 } 74 theta *= 2; 75 } 76 i = 0; 77 for (j = 1; j < n - 1; j++) 78 { 79 for (k = n >> 1; k >(i ^= k); k >>= 1); 80 if (j < i) 81 { 82 xr = ar[j]; 83 xi = ai[j]; 84 ar[j] = ar[i]; 85 ai[j] = ai[i]; 86 ar[i] = xr; 87 ai[i] = xi; 88 } 89 } 90} 91int main(int argc, char *argv[]) { 92 93 FILE *fp; 94 int i; 95 96 //音声ファイル読み込み 97 fp = fopen(WAV_NAME, "rb"); 98 if (!fp) return endWithError("Failed to open the wav file"); 99 100 //Check that the WAVE file is OK 101 fread(type, sizeof(char), 4, fp); 102 if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') 103 return endWithError("No RIFF"); 104 105 fread(&parameter, sizeof(DWORD), 1, fp); 106 fread(type, sizeof(char), 4, fp); 107 if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') 108 return endWithError("not WAVE"); 109 110 fread(type, sizeof(char), 4, fp); 111 if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') 112 return endWithError("not fmt "); 113 114 fread(&chunkSize, sizeof(DWORD), 1, fp); //ここからchunkSizeバイト分がwavのパラメータ領域 115 fread(&formatType, sizeof(short), 1, fp); //基本的にpcm形式 116 fread(&channels, sizeof(short), 1, fp); //wavのチャンネル数 117 fread(&sampleRate, sizeof(DWORD), 1, fp); //サンプリング周波数 118 fread(&avgBytesPerSec, sizeof(DWORD), 1, fp); //1秒間の平均転送レート(=channels*sampleRate*bitsPerSample / 8) 119 fread(&bytesPerSample, sizeof(short), 1, fp); //各サンプル数のbyte数(例えば、16bit, 2channelsなら4) 120 fread(&bitsPerSample, sizeof(short), 1, fp); //量子化ビット数 (16, 8) 121 122 123 for (i = 0; i < 256; i++) { 124 fread(type, sizeof(char), 1, fp); 125 if (type[0] == 'd') { 126 fread(type, sizeof(char), 1, fp); 127 if (type[0] == 'a') { 128 fread(type, sizeof(char), 1, fp); 129 if (type[0] == 't') { 130 fread(type, sizeof(char), 1, fp); 131 if (type[0] == 'a') { 132 break; 133 } 134 } 135 } 136 } 137 if (i == 255) { 138 return 0; 139 } 140 } 141 142 fread(&dataSize, sizeof(unsigned long), 1, fp); //上下bit,左右chがばらばらの長さ 143 144 cout << "Size: " << parameter << "\n"; 145 cout << "Chunk Size: " << chunkSize << "\n"; 146 cout << "Format Type: " << formatType << "\n"; 147 cout << "Channels: " << channels << "\n"; 148 cout << "Sample Rate: " << sampleRate << "\n"; 149 cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n"; 150 cout << "Bytes Per Sample: " << bytesPerSample << "\n"; 151 cout << "Bits Per Sample: " << bitsPerSample << "\n"; 152 cout << "Data Size: " << dataSize << "\n\n"; 153 154 memory = bitsPerSample / 8; //一度に読み込む長さ(ex.16bitなら2byteずつ) 155 WAV_LENGTH = dataSize / memory; //波形データ長 156 157 wav_data = new signed short[WAV_LENGTH]; //読み込んだデータを入れる 158 159 fread(wav_data, memory, WAV_LENGTH, fp); 160 161 fclose(fp); 162 163 //マイクセットアップ 164 ALCdevice* mic = alcCaptureOpenDevice(nullptr, 48000, AL_FORMAT_MONO16, BUFFER_SIZE); 165 //スピーカーセットアップ 166 ALCdevice* speaker = alcOpenDevice(nullptr); 167 //コンテキスト 168 ALCcontext *context = alcCreateContext(speaker, NULL); 169 alcMakeContextCurrent(context); 170 171 //バッファとソース宣言 172 ALuint buf; 173 ALuint sou; 174 alGenBuffers(1, &buf); 175 alGenSources(1, &sou); 176 177 178 alBufferData(buf, AL_FORMAT_MONO16, &wav_data[0], WAV_LENGTH * sizeof(signed short), sampleRate); 179 alSourcei(sou, AL_BUFFER, buf); 180 alSourcePlay(sou); 181 alSourcei(sou, AL_LOOPING, AL_TRUE); 182 ALshort* buffer; 183 buffer = new ALshort[BUFFER_SIZE]; 184 output = new ALshort[S_LENGTH * T]; 185 //録音開始 186 alcCaptureStart(mic); 187 //録音を制御 188 int count = 0; 189 ALint sample; 190 Sleep(50); 191 while (1) { 192 //録音可能なバッファ長を取得 193 alcGetIntegerv(mic, ALC_CAPTURE_SAMPLES, sizeof(sample), &sample); 194 //再生が終わり、録音が可能なとき 195 if (sample > 0) { 196 //録音してstoreに格納 197 alcCaptureSamples(mic, (ALCvoid*)&buffer[0], sample); 198 199 for (i = 0; i < sample; i++) { 200 if (count + i > S_LENGTH * T) { 201 break; 202 } 203 output[count + i] = buffer[i]; 204 } 205 if (count + sample > S_LENGTH * T) { 206 break; 207 } 208 count += sample; 209 } 210 } 211 alcCaptureStop(mic); 212 alSourceStop(sou); 213 214 215 //start up 216 // GLFW初期化 217 if (!glfwInit()) { 218 return -1; 219 } 220 221 222 //create window 223 GLFWwindow *const window(glfwCreateWindow(Window_Width, Window_Height, argv[0], NULL, NULL)); 224 //GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonitor(), NULL); //fullscreen 225 if (window == NULL) { 226 cout << "Error" << endl; 227 glfwTerminate(); 228 return 1; 229 } 230 231 //検出ループ 232 //マウスボタンループ 233 glfwSetMouseButtonCallback(window, mouse_button_callback); 234 //ウィンドウサイズループ 235 glfwSetWindowSizeCallback(window, window_size_callback); 236 237 // 下準備 238 //処理対象にする 239 glfwMakeContextCurrent(window); 240 // 垂直同期のタイミングを待つ 241 glfwSwapInterval(1); 242 //背景色を指定 243 glClearColor(0.0, 0.0, 0.0, 1.0); 244 //座標系を検出基準にする 245 setting_viewport(Window_Width, Window_Height); 246 247 // ウィンドウが開いている間繰り返す 248 while (!glfwWindowShouldClose(window)) { 249 fncDisplay(); 250 // カラーバッファを入れ替える 251 glfwSwapBuffers(window); 252 //これがないと検出できない 253 glfwPollEvents(); 254 // すぐに描画 255 fflush(stdout); 256 } 257 //GLFWを終了する 258 //glfwTerminate(); 259 // FFT用入力信号 実部 虚部 260 double* sr = new double[S_LENGTH]; 261 double* si = new double[S_LENGTH]; 262 double* yr = new double[S_LENGTH]; 263 double* yi = new double[S_LENGTH]; 264 265 //録音した信号 266 for (i = 0; i < S_LENGTH; i++) { 267 sr[i] = output[i+save]; 268 } 269 for (i = 0; i < S_LENGTH; i++) { 270 si[i] = 0; 271 } 272 fft(S_LENGTH, sr, si); 273 //逆フィルタ(itsp信号) 274 for (i = 0; i < S_LENGTH; i++) { 275 yr[i] = wav_data[S_LENGTH - 1 - i]; 276 } 277 for (i = 0; i < S_LENGTH; i++) { 278 yi[i] = 0; 279 } 280 fft(S_LENGTH, yr, yi); 281 //周波数領域で畳み込み 282 for (i = 0; i < S_LENGTH; i++) { 283 sr[i] = sr[i] * yr[i]; 284 } 285 for (i = 0; i < S_LENGTH; i++) { 286 si[i] = si[i] * yi[i]; 287 } 288 fft(S_LENGTH, sr, si); 289 290 //出力 291 fncMax(&sr[0], S_LENGTH, 1); 292 fp = fopen("data.csv", "w"); 293 fprintf(fp, "番号, 録音, 音源, インパルス\n"); 294 if (!fp) return endWithError("Failed to open the csv file"); 295 for (i = 0; i < S_LENGTH; i+=8) { 296 fprintf(fp, "%d, %d, %d, %lf\n", i, output[i], wav_data[i], sr[i]); 297 } 298 fclose(fp); 299 300 Output(&output[save], S_LENGTH * T - save); 301 302 delete[] wav_data; 303 delete[] output; 304 delete[] sr; 305 delete[] si; 306 delete[] yr; 307 delete[] yi; 308 309 alDeleteSources(1, &sou); 310 alDeleteBuffers(1, &buf); 311 312 alcMakeContextCurrent(nullptr); //操作対象のコンテキストを解除 313 alcDestroyContext(context); //コンテキストを破棄 314 alcCaptureCloseDevice(mic); 315 alcCloseDevice(speaker); 316 317 return 0; 318}

試したこと

原因をたどってみたところ、glfwInit()か、newを使ったメモリ確保の時にエラーが起きているようなのです。
読み込んでいる音源などは常に同じものなため、領域外を処理しているところはない気がするのですが・・・
一応VisualStudioのバージョンを変えて試してみましたが、動作が不安定なことは変わりませんでした。

補足情報(FW/ツールのバージョンなど)

VisualStudio2015,2019

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

VisualStudio2015,2019

とのことで、デバッグビルドを行っているものと思いますが
MSVCのデバッグビルドの場合、delete/delete[]時に末尾もしくは、先頭の領域外への書き込みが行われている場合
エラーを吐くことがあります。

見た感じ、そのエラーのようなので、どのポインタをdelete/delete[]した時にエラーが出ているのか。
をまず見ます。
あとは、そのポインタの使い方を精査し領域外アクセスを行っていないかを調べるとよいでしょう。

投稿2019/08/22 00:19

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takenok0

2019/08/22 02:10

回答ありがとうございます。 deleteしたときにも気を配って検証したいと思います。
guest

0

このように不規則にエラーが出るとかいうのは、たいていメモリ破壊を起こしている場合の典型的な症状です
C/C++ではエラーが起きたからといってエラーを出してくれません
運が悪ければ、エラーも出ず結果がなにかおかしいだけ、ということも起こります。

エラーが起きているよう、なのであれば、そこにブレークポイントを設定するなりして実行を止め、変数の内容や実行結果をモニタしてみましょう。
また、1行づつ実行して、想定した動作を違うところを探していきましょう

投稿2019/08/21 23:28

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takenok0

2019/08/22 02:09

回答ありがとうございます。 アドバイスの通り、ブレークポイントで探ってみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問