[英]C++ error code: std::bad_alloc at memory location
我現在正在使用 Visual Studio,我對收到的錯誤消息有疑問。
它說“memory 位置的 std::bad_alloc”。
我想這意味着我沒有足夠的 memory。 我正在使用 arrays 進行計算,我認為問題出在每個數組的大小上。
首先我使用堆棧而不是堆,所以我動態分配每個數組。 但是,我仍然收到相同的錯誤消息。
如果我減小數組的大小,我可以運行此代碼,但我需要將它與更大的 arrays 一起使用。
如果我使用更好的計算機,我可以運行此代碼嗎? 我不確定如何減少運行此代碼所需的 memory .... 我應該使用更少的 arrays 嗎?
下面,我把整個代碼,以防萬一......
提前致謝。
include <iostream>
#include <cstdio>
#include <chrono>
#include <vector>
#include <math.h> // power
#include <cmath> // abs
#include <fstream>
#include <omp.h>
using namespace std;
using namespace chrono;
// Dynamically allocation with values(double)
void dallo_fn(double**** pMat, int Na, int Nd, int Ny) {
double*** Mat = new double** [Na];
for (int i = 0; i < Na; i++) {
Mat[i] = new double* [Nd];
for (int j = 0; j < Nd; j++) {
Mat[i][j] = new double[Ny];
fill_n(Mat[i][j], Ny, 1);
}
}
*pMat = Mat;
}
// Dynamically allocation without values(double)
void dallo_fn0(double**** pMat, int Na, int Nd, int Ny) {
double*** Mat = new double** [Na];
for (int i = 0; i < Na; i++) {
Mat[i] = new double* [Nd];
for (int j = 0; j < Nd; j++) {
Mat[i][j] = new double[Ny];
}
}
*pMat = Mat;
}
// Dynamically allocation without values(int)
void dallo_fn1(int**** pMat, int Na, int Nd, int Ny) {
int*** Mat = new int** [Na];
for (int i = 0; i < Na; i++) {
Mat[i] = new int* [Nd];
for (int j = 0; j < Nd; j++) {
Mat[i][j] = new int[Ny];
}
}
*pMat = Mat;
}
// Utility function
double utility(double a, double a_f, double d, double d_f, double y, double sig, double psi, double delta, double R) {
double C;
C = y + a - a_f / R - (d_f - (1 - delta) * d);
double result;
if (C > 0) {
result = 1 / (1 - 1 / sig) * pow(pow(C, psi) * pow(d_f, 1 - psi), (1 - 1 / sig));
}
else {
result = -999999;
}
return result;
}
int main()
{
#if defined _OPENMP
omp_set_num_threads(8);
#endif
double duration;
// Iteration Parameters
double tol = 0.000001;
double itmax = 200;
double H = 15;
// Model Parameters and utility function
double sig = 0.75;
double beta = 0.95;
double psi = 0.5;
double delta = 0.1;
double R = 1 / beta - 0.00215;
// =============== 2. Discretizing the state space =========================
// Size of arrays
const int Na = 2 * 91;
const int Nd = 1 * 71;
const int Ny = 3;
// Variables for discretization of state space
const double amin = -2;
const double amax = 7;
const double dmin = 0.01;
const double dmax = 7;
const double ymin = 0.5;
const double ymax = 1.5;
const double Ptrans[3] = { 0.2, 0.6, 0.2 };
// Discretization of state space
double ca = (amax - amin) / (Na - 1.0);
double cd = (dmax - dmin) / (Nd - 1.0);
double cy = (ymax - ymin) / (Ny - 1.0);
double* A = new double[Na];
double* Y = new double[Ny];
double* D = new double[Nd];
for (int i = 0; i < Na; i++) {
A[i] = amin + i * ca;
}
for (int i = 0; i < Nd; i++) {
D[i] = dmin + i * cd;
}
for (int i = 0; i < Ny; i++) {
Y[i] = ymin + i * cy;
}
// === 3. Initial guesses, Variable initialization and Transition matrix ===
// Initial guess for value function
double*** V;
dallo_fn(&V, Na, Nd, Ny);
double*** Vnew;
dallo_fn(&Vnew, Na, Nd, Ny);
// Initialization of other variables
double Val[Na][Nd];
double Vfuture[Na][Nd];
double** temphoward = new double* [Na];
for (int i = 0; i < Na; i++)
{
temphoward[i] = new double[Nd];
}
double*** Vhoward;
dallo_fn0(&Vhoward, Na, Nd, Ny);
double*** tempdiff;
dallo_fn0(&tempdiff, Na, Nd, Ny);
int*** maxposition_a;
dallo_fn1(&maxposition_a, Na, Nd, Ny);
int*** maxposition_d;
dallo_fn1(&maxposition_d, Na, Nd, Ny);
double** mg_A_v = new double* [Na];
for (int i = 0; i < Na; i++)
{
mg_A_v[i] = new double[Nd];
}
for (int j = 0; j < Nd; j++) {
for (int i = 0; i < Na; i++) {
mg_A_v[i][j] = A[i];
}
}
double** mg_D_v = new double* [Na];
for (int i = 0; i < Na; i++)
{
mg_D_v[i] = new double[Nd];
}
for (int j = 0; j < Nd; j++) {
for (int i = 0; i < Na; i++) {
mg_D_v[i][j] = D[j];
}
}
double***** Uvec = new double**** [Na];
for (int i = 0; i < Na; i++) {
Uvec[i] = new double*** [Nd];
for (int j = 0; j < Nd; j++) {
Uvec[i][j] = new double** [Ny];
for (int k = 0; k < Ny; k++) {
Uvec[i][j][k] = new double* [Na];
for (int l = 0; l < Na; l++) {
Uvec[i][j][k][l] = new double[Nd];
}
}
}
}
for (int i = 0; i < Na; i++) {
for (int j = 0; j < Nd; j++) {
for (int k = 0; k < Ny; k++) {
for (int l = 0; l < Na; l++) {
for (int m = 0; m < Nd; m++) {
Uvec[i][j][k][l][m] = utility(A[i], mg_A_v[l][m], D[j], mg_D_v[l][m], Y[k], sig, psi, delta, R);
}
}
}
}
}
// Value function iteration
int it;
double dif;
double max;
it = 0;
dif = 1;
// ================ 4. Value function iteration ============================
while (dif >= tol && it <= itmax) {
system_clock::time_point start = system_clock::now();
it = it + 1;
// V = Vnew;
for (int i = 0; i < Na; i++) {
for (int j = 0; j < Nd; j++) {
for (int k = 0; k < Ny; k++) {
V[i][j][k] = Vnew[i][j][k];
}
}
}
for (int i = 0; i < Na; i++) {
for (int j = 0; j < Nd; j++) {
Vfuture[i][j] = 0;
for (int k = 0; k < Ny; k++) {
Vfuture[i][j] += beta * Ptrans[k] * Vnew[i][j][k]; // + beta * Ptrans[1] * Vnew[i][j][1] + beta * Ptrans[2] * Vnew[i][j][2]; // Why is this different from Vfuture[i][j] += beta * Vnew[i][j][k] * Ptrans[k]; with for k
}
}
}
#pragma omp parallel for private(Val)
for (int a = 0; a < Na; a++) {
for (int b = 0; b < Nd; b++) {
for (int c = 0; c < Ny; c++) {
max = -99999;
for (int d = 0; d < Na; d++) {
for (int e = 0; e < Nd; e++) {
Val[d][e] = Uvec[a][b][c][d][e] + Vfuture[d][e];
if (max < Val[d][e]) {
max = Val[d][e];
maxposition_a[a][b][c] = d;
maxposition_d[a][b][c] = e;
}
}
}
Vnew[a][b][c] = max;
}
}
}
// Howard improvement
for (int h = 0; h < H; h++) {
for (int i = 0; i < Na; i++) {
for (int j = 0; j < Nd; j++) {
for (int k = 0; k < Ny; k++) {
Vhoward[i][j][k] = Vnew[i][j][k];
}
}
}
for (int i = 0; i < Na; i++) {
for (int j = 0; j < Nd; j++) {
for (int k = 0; k < Ny; k++) {
temphoward[i][j] = beta * Vhoward[maxposition_a[i][j][k]][maxposition_d[i][j][k]][0] * Ptrans[0]
+ beta * Vhoward[maxposition_a[i][j][k]][maxposition_d[i][j][k]][1] * Ptrans[1]
+ beta * Vhoward[maxposition_a[i][j][k]][maxposition_d[i][j][k]][2] * Ptrans[2];
Vnew[i][j][k] = temphoward[i][j] + Uvec[i][j][k][maxposition_a[i][j][k]][maxposition_d[i][j][k]];
}
}
}
}
// Calculate Diff
dif = -100000;
for (int i = 0; i < Na; i++) {
for (int j = 0; j < Nd; j++) {
for (int k = 0; k < Ny; k++) {
tempdiff[i][j][k] = abs(V[i][j][k] - Vnew[i][j][k]);
if (tempdiff[i][j][k] > dif) {
dif = tempdiff[i][j][k];
}
}
}
}
system_clock::time_point end = system_clock::now();
std::chrono::duration<double> sec = end - start;
cout << dif << endl;
cout << it << endl;
cout << sec.count() << endl;
}
for (int k = 0; k < Ny; k++) {
for (int i = 0; i < Na; i++) {
for (int j = 0; j < Nd; j++) {
cout << Vnew[i][j][k];
}
cout << '\n';
}
}
cout << omp_get_max_threads() << endl;
}
誠然,代碼很漂亮 memory 餓了,但適用於我的 8GB 機器。 請確保您的目標是 x64 平台,否則您會達到 4GB 的固有限制。
是的,只要有足夠的 memory,您就可以運行此代碼。 我剛剛在我的機器上用 64GB 的 RAM 測試過它,它運行得很好。
減少所需 memory 數量的一種方法是使用float
s 而不是double
s,因為它們占用了一半的大小。
此外,正如其他人在評論中所建議的那樣,您可以將多維結構表示為 1d arrays 並計算數組中的索引,而不是實際嵌套 arrays。 好處是你擺脫了大量的指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.