こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Windowsでは出るエラーでMacでは出ない

現在、Visual C++ 2013 Expressを使っているのですが、そちらではエラーが出るのに、MacbookのXcodeで走らせたらエラーも出ずに正常に実行することができます。

いったい何が原因でエラーが起こっているのでしょうか?

エラーメッセージは"XXXXX.exe has triggered a breakpoint."で"malloc.c"のタブがVC++上に開きます。以下がそのコードになるのですが、アドバイス宜しくお願い致します。


#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <complex>
#include <stdlib.h>

using namespace std;

typedef complex<double> dcmplx;
complex<double> M_i = dcmplx(0, 1);

//---------------------------------------------------------------
// Characteristic Function
dcmplx* CharFunc(double alpha, double* nu, double s0, double r, double q, double sigma, double t, int N)
{
dcmplx* out = (dcmplx*)malloc(sizeof(dcmplx) * N);
dcmplx* u = (dcmplx*)malloc(sizeof(dcmplx) * N);
for (int j = 0; j < N; ++j){ // j = 1,...,N
u[j] = nu[j] - (alpha + 1) * M_i;
out[j] = exp(M_i*(log(s0) + (r - q - sigma*sigma / 2.0)*t)*u[j] - sigma*sigma * u[j] * u[j] * t / 2.0);
}
return out;
}
// Characteristic Function for C
dcmplx CharFuncC(double u, double s0, double K, double r, double q, double sigma, double t, int N)
{
return exp(M_i*((log(s0) - log(K)) + (r - q - sigma*sigma / 2.0)*t)*u - sigma*sigma * u*u * t / 2.0);
}

//---------------------------------------------------------------
// Main
int main(int, char**) {
double alpha[] = { -1.2, -1.5, -5.0, -10.0 };
double eta;
double s0;
double r;
double q;
double sigma;
double t;
double K;
int pow2;
int N;
int m_atm = 0;

FILE *fp;
if (!(fp = fopen("inputa.txt", "r"))){
printf("File \'inputa\' could not be opened!");
exit(-1);
}
fscanf(fp, "%lg%lg%lg%lg%lg%lg%d", &eta, &s0, &r, &q, &sigma, &t, &pow2);

double a;
double b;
double v;
double abs_ab[] = { 2.0, 5.0, 10.0, 20.0 };
double sum =0;

for (pow2 = 7; pow2 <= 10; ++pow2){

N = (int)pow(2.0, pow2);
double *nu = (double*)malloc(sizeof(double)* N);// nu * (b - a) / M_PI;
double *Vp = (double*)malloc(sizeof(double)* N);
double *chi = (double*)malloc(sizeof(double)* N);
double *phi = (double*)malloc(sizeof(double)* N);
dcmplx *Phi = (dcmplx*)malloc(sizeof(double)* N);

for (int i = 0; i < 4; ++i){
b = abs_ab[i];
a = -b;
cout << "N:" << N << ", (a, b): (" << a << ", " << b << ")" << endl;
for (K = 1600; K <= 1900; K += 100){
for (int k = 0; k < N; ++k){

nu[k] = k * M_PI / (b - a);

// chi for Put with (c,d) = (a,0)
chi[k] = 1.0 / (1.0 + nu[k] * nu[k]) * (cos(nu[k] * (-a)) - exp(a) + nu[k] * sin(nu[k] * (-a)));

// phi for Put with (c,d) = (a,0)
phi[k] = sin(nu[k] * (-a)) * (1.0 / nu[k]);
phi[0] = -a;

// COS expasion coeff V for Put
Vp[k] = (2.0 / (b - a)) * K * (-chi[k] + phi[k]);

// Characteristic Function for C, (just different argument inputs)
nu[k] = k * M_PI / (b - a);
Phi[k] = CharFuncC(nu[k], s0, K, r, q, sigma, t, N);

sum += real(Phi[k] * exp(-M_i*(k*M_PI) * a / (b - a)))*Vp[k];
if (k == 0) sum /= 2.0;
}
v = exp(-r*t)*sum;
cout << "strike=" << K << ", price=" << v << endl;
sum = 0.0;
}
}
}
system("Pause");
return 0;
}

投稿日時 - 2014-12-01 15:11:24

QNo.8843632

すぐに回答ほしいです

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

>XXXXX.exe has triggered a breakpoint.

意味は「XXXXX.exeはブレークポイントで停止した」です。

malloc.cの所で出るとしたら「ヒープ領域を破壊している」と思います。

Visual C++ 2013の場合、ヒープ領域を破壊すると、mallocの内部で「ブレークポイントで例外停止」するようになっています。

んで

dcmplx *Phi = (dcmplx*)malloc(sizeof(double)* N);

は、明らかにおかしいです。

dcmplx型をN個分確保したいのに、double型をN個分しか確保してません。

正しくは

dcmplx *Phi = (dcmplx*)malloc(sizeof(dcmplx)* N);

じゃないかと思います。

あと、MacのXcodeでは、ヒープを破壊すると

APPNAME_XXX(????,0x????????) malloc: *** error for object 0x????????: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

と言うエラーが出る筈だけど、Visual C++ 2013とは実装が異なるので、偶然「使ってないヒープ領域を壊しただけ」の場合は、エラーも出ないし、何も起きず、普通に「ちゃんと実行したフリ」をする筈です。

ヒープ領域は、壊し方によっては、Visual C++ 2013でも「エラーも出ないし、何も起きず、普通にちゃんと実行したフリをする」で終わるので、なかなかバグが見付からない場合もあります。

投稿日時 - 2014-12-01 16:21:44

お礼

おお、何という単純なミス(ただ、仕組みについては複雑?)だったんでしょう!
メモリサイズを確保するために同じようにそれ以外の変数同様に行っていたため、コピーペーストで最後の部分だけ書き換え忘れたようです!

修正したら、正しく実行できました!ありがとうございます!

投稿日時 - 2014-12-01 16:55:01

このQ&Aは役に立ちましたか?

15人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

追記の追記。

mallocされたメモリが開放されないまま、次々に新しいメモリが確保されていき、使い終わったメモリが誰にも開放されないままプログラムが終了している(メモリリークしている)が、Nの最大値は1024くらいなので、ほぼ実害は無い。

doubleの値が数千個分メモリリークした所で今のOSは屁でもないので、ユーザーメモリがちょっと減ってオシマイになるだけ。

このプログラムを何千万回も動かすとか、ずっと常駐させて繰り返し動かすとかすれば、実害が出るだろうけど。

投稿日時 - 2014-12-01 16:47:25

お礼

他の方への質問の回答までありがとうございます!これくらいでは問題ないとのことで。
ただ、できるだけ解放する癖をつけておきます!

投稿日時 - 2014-12-01 17:19:18

ANo.4

追記。

scanf系関数について
http://www.isc.meiji.ac.jp/~re00030/jse/scanf.html

scanf系は

浮動小数点(次の3つは同じである)

f 入力を浮動小数(float型)と解釈
e,E 入力を浮動小数(float型)と解釈
g,G 入力を浮動小数(float型)と解釈

オプション

l long型の整数またはdouble型の浮動小数点を意味する(小文字のエル)

って事になっている。

なので、%gって書いたら、floatのポインタが指定されているとして実行するんで、正しく代入されない。

doubleのポインタを指定する場合は、%lf、%le、%lE、%lg、%lGのどれかを指定すること。

「%gで良い」と言う回答は無視すること。

投稿日時 - 2014-12-01 16:37:00

お礼

ありがとうございます!分かって書いたつもりなのに指摘されるとそうなのかな?と思ってしまいました。
他の回答も順次チェックしてコメントしていきます。

投稿日時 - 2014-12-01 16:46:55

ANo.2

Wr5

とりあえず……malloc()して、そのあとどこで解放していますかね?
>for (pow2 = 7; pow2 <= 10; ++pow2){
のループでそれぞれNはいくつになりますかね?

投稿日時 - 2014-12-01 15:56:14

お礼

malloc()と同じループの中に、

free(nu);
free(Vp);
free(chi);
free(phi);
free(Phi);

を入れてみましたが、dcmplx *Phi = (dcmplx*)malloc(sizeof(double)* N)の部分をdoubleのままにしていたら今まで同様のエラーが出ました。dcmplxにしたら、freeをいれても実行できました。

この場合、このfreeは必要なんでしょうか?癖をつけておいた方がいいとか。また、書き方としてはこれで問題ないですよね?

投稿日時 - 2014-12-01 17:01:59

ANo.1

よく見る気はないけど,とりあえず
fscanf(fp, "%lg%lg%lg%lg%lg%lg%d", &eta, &s0, &r, &q, &sigma, &t, &pow2);
これの%lgはC89やC++ではエラーじゃないのかなあ。C99では無視されるようだけど。
普通に%gにすればいいのに。

投稿日時 - 2014-12-01 15:54:42

あなたにオススメの質問