多个文件的内存分配错误“在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用” [C ++]

Posted

技术标签:

【中文标题】多个文件的内存分配错误“在抛出 \'std :: bad_alloc\' what (): std :: bad_alloc 的实例后终止调用” [C ++]【英文标题】:Memory allocation error for multiple files “terminate called after throwing an instance of 'std :: bad_alloc' what (): std :: bad_alloc” [C ++]多个文件的内存分配错误“在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用” [C ++] 【发布时间】:2020-11-03 05:57:18 【问题描述】:

我正在为数字语音信号处理项目使用分类器算法。开发此算法是为了在单个向量中接收所有音频信号以进行处理,但我遇到了问题,因为我正在处理的文件数量非常大并且正在生成错误“在抛出一个'std :: bad_alloc 'what (): std :: bad_alloc 的实例。我想知道是否可以在不超出可用内存空间的情况下对读取文件并将它们存储在向量中的代码进行任何更改。

读取文件的代码:

string filename;
    filename="C:\\Users\\marcu\\Desktop\\TCC\\Arquivos_10780\\Arquivos_DFT_TXT_512\\PA_D_00";

    std::vector<double> c;

    for(int j=1; j<=5400; j++)
    
        stringstream ss;
        ss << filename << setw(5) << setfill('0') << j << "_bonafide_DFT.txt";

        std::ifstream f;
        f.open(ss.str().c_str());

        if (f.is_open())
        
            double num;

            while (f >> num)
                c.push_back(num);

            f.close();
        
        else
        
            f.close();
            continue;
        
    

    for(int j=5401; j<=29700; j++)
    
        stringstream ss;
        ss << filename << setw(5) << setfill('0') << j << "_spoof_DFT.txt";

        std::ifstream f;
        f.open(ss.str().c_str());

        if (f.is_open())
        
            double num;

            while (f >> num)
                c.push_back(num);

            f.close();
        
        else
        
            f.close();
            continue;
        
    

完整代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<stdlib.h>
#include<iomanip>
#include<sstream>

using namespace std;

double mean_similarities(double**,int,int);//vectors, number of vectors, their dimension

int main()

    const int number_of_classes=2;
    int number_of_feature_vectors_in_class[number_of_classes];
    number_of_feature_vectors_in_class[0]=2700;
    number_of_feature_vectors_in_class[1]=8080;
    const int dimension_of_each_feature_vector=512;

////////////////////////////////////////////////////////////////////////////////////////////
/*
Example: 3 classes and 4 vectors of dimension 2 in each class
0.90,0.12,0.88,0.14,0.88,0.13,0.89,0.11   //0.88---0.90 ; 0.11---0.14
0.55,0.53,0.53,0.55,0.54,0.54,0.56,0.54   //0.53---0.56 ; 0.53---0.55
0.10,0.88,0.11,0.86,0.12,0.87,0.11,0.88   //0.10---0.12 ; 0.86---0.88  

double c[]= 
0.90,0.12,0.88,0.14,0.88,0.13,0.89,0.11,
0.55,0.53,0.53,0.55,0.54,0.54,0.56,0.54,
0.10,0.88,0.11,0.86,0.12,0.87,0.11,0.88
//all vectors in class C_1, followed by all vectors in C_2, ...., followed by all in C_n
            ;
*/
////////////////////////////////////////////////////////////////////////////////////////////

    string filename;
    filename="C:\\Users\\marcu\\Desktop\\TCC\\Arquivos_10780\\Arquivos_DFT_TXT_512\\PA_D_00";

    std::vector<double> c;

    for(int j=1; j<=5400; j++)
    
        stringstream ss;
        ss << filename << setw(5) << setfill('0') << j << "_bonafide_DFT.txt";

        std::ifstream f;
        f.open(ss.str().c_str());

        if (f.is_open())
        
            double num;

            while (f >> num)
                c.push_back(num);

            f.close();
        
        else
        
            f.close();
            continue;
        
    

    for(int j=5401; j<=29700; j++)
    
        stringstream ss;
        ss << filename << setw(5) << setfill('0') << j << "_spoof_DFT.txt";

        std::ifstream f;
        f.open(ss.str().c_str());

        if (f.is_open())
        
            double num;

            while (f >> num)
                c.push_back(num);

            f.close();
        
        else
        
            f.close();
            continue;
        
    

////////////////////////////////////////////////////////////////////////////////////////////
//edit whatever you need, according to the feature vectors of your problem, ABOVE this line.
//Do NOT change anything BELOW this line !!!!!
////////////////////////////////////////////////////////////////////////////////////////////
    double*** C=new double**[number_of_classes];
    for(int i=0; i<number_of_classes; i++)
        C[i]=new double*[number_of_feature_vectors_in_class[i]];
    for(int i=0; i<number_of_classes; i++)
        for(int j=0; j<number_of_feature_vectors_in_class[i]; j++)
            C[i][j]=new double[dimension_of_each_feature_vector];
    int l=0;
    for(int i=0; i<number_of_classes; i++)
        for(int j=0; j<number_of_feature_vectors_in_class[i]; j++)
            for(int k=0; k<dimension_of_each_feature_vector; k++)
            
                C[i][j][k]=c[l];
                l++;
            

//Debug info only
//for(int i=0;i<number_of_classes;i++)
//  for(int j=0;j<number_of_feature_vectors_in_class[i];j++)
//      for(int k=0;k<dimension_of_each_feature_vector;k++)
//          printf("\nclass %d vector %d element %d is %.3f",i,j,k,C[i][j][k]);
//getchar();
    double Y[number_of_classes];
    for(int i=0; i<number_of_classes; i++)
        Y[i]=mean_similarities(C[i],number_of_feature_vectors_in_class[i],dimension_of_each_feature_vector);
    double alpha=Y[0];
    for(int i=1; i<number_of_classes; i++)
        if(Y[i]<alpha)
            alpha=Y[i];
    printf("\nALPHA: %.3f",alpha);
    double** smallest_range_vector_for_class=new double*[number_of_classes];
    for(int i=0; i<number_of_classes; i++)
        smallest_range_vector_for_class[i]=new double[dimension_of_each_feature_vector];
    for(int i=0; i<number_of_classes; i++)
        for(int k=0; k<dimension_of_each_feature_vector; k++)
            smallest_range_vector_for_class[i][k]=C[i][0][k];
    for(int i=0; i<number_of_classes; i++)
        for(int j=1; j<number_of_feature_vectors_in_class[i]; j++)
            for(int k=0; k<dimension_of_each_feature_vector; k++)
                if(C[i][j][k]<smallest_range_vector_for_class[i][k])
                    smallest_range_vector_for_class[i][k]=C[i][j][k];

//Debug info only
//for(int i=0;i<number_of_classes;i++)
//  for(int k=0;k<dimension_of_each_feature_vector;k++)
//          printf("\nclass %d smallest component %d is %.3f",i,k,smallest_range_vector_for_class[i][k]);
    double** largest_range_vector_for_class=new double*[number_of_classes];
    for(int i=0; i<number_of_classes; i++)
        largest_range_vector_for_class[i]=new double[dimension_of_each_feature_vector];
    for(int i=0; i<number_of_classes; i++)
        for(int k=0; k<dimension_of_each_feature_vector; k++)
            largest_range_vector_for_class[i][k]=C[i][0][k];
    for(int i=0; i<number_of_classes; i++)
        for(int j=1; j<number_of_feature_vectors_in_class[i]; j++)
            for(int k=0; k<dimension_of_each_feature_vector; k++)
                if(C[i][j][k]>largest_range_vector_for_class[i][k])
                    largest_range_vector_for_class[i][k]=C[i][j][k];

//Debug info only
//for(int i=0;i<number_of_classes;i++)
//  for(int k=0;k<dimension_of_each_feature_vector;k++)
//          printf("\nclass %d largest component %d is %.3f",i,k,largest_range_vector_for_class[i][k]);
    int R=0;
    int F=0;
    for(int ia=0; ia<number_of_classes; ia++)
        for(int ib=0; ib<number_of_classes; ib++)
            for(int j=0; j<number_of_feature_vectors_in_class[ib]; j++)
                for(int k=0; k<dimension_of_each_feature_vector; k++)
                
                    if(ib!=ia)
                    
                        if((C[ib][j][k]>smallest_range_vector_for_class[ia][k])&&(C[ib][j][k]<largest_range_vector_for_class[ia][k]))
                            R++;
                        F++;
                    
                
    double beta=((double)(R))/((double)(F));
    printf("\nBETA: %.3f",beta);
    printf("\nP=(G1,G2)=(%.3f,%.3f)",alpha-beta,alpha+beta-1);
    printf("\nDistance from P to (1,0): %.3f",sqrt(pow((alpha-beta)-1,2)+pow(alpha+beta-1,2)));
    printf("\n\n");

/////////////////////////////////////////////
////////////////////////////////////////////
double mean_similarities(double** v,int n, int t)

    double largest;
    double smallest;
    double* s=new double[t];
    for(int i=0; i<t; i++)
    
        smallest=1;
        largest=0;
        for(int j=0; j<n; j++)
        
            if(v[j][i]>largest)
                largest=v[j][i];
            if(v[j][i]<smallest)
                smallest=v[j][i];
        
        s[i]=1-(largest-smallest);
    
    double m=0;
    for(int i=0; i<t; i++)
        m+=s[i];
    m/=((double)(t));
    return(m);

PS:为了找到最好的分类器结果,我需要将文件大小(每个文件的信息量)更改为越来越大的值。起初是 512 点,但每次执行时我都会将该值加倍,直到达到 8192,但是当我尝试使用 16384 时,代码崩溃了。我正在处理 10780 个文件,其中每个文件都具有相同的尺寸,并在检查结果时增加它。

【问题讨论】:

无关:在现实世界中Three Star Programmers应该避免。 @user4581301 这和三星级编程有什么关系,我没有看到任何动态内存分配之类的?? @YunfeiChen 向下滚动到Do NOT change anything BELOW this line !!!!! 下一行是一个 3D 阵列,以最痛苦的方式完成。但是,在这种情况下,它可能是合理的,因为它使内存块的大小保持可管理。虽然像筛子一样漏水 @user4581301 我注意到了几件事:首先,他看起来有一个额外的 else 语句......而且看起来他正在向文件写入数万次,关闭并打开,只是好奇他的程序到底有多贵,看起来它会导致系统崩溃??或者花点时间...... @user4581301 哇,看起来很丑,你怎么删除那个怪物?当然,在你完成之后...... 【参考方案1】:

首先,你下面有很多问题:

double** largest_range_vector_for_class=new double*[number_of_classes];
    for(int i=0; i<number_of_classes; i++)
        largest_range_vector_for_class[i]=new double[dimension_of_each_feature_vector];
    for(int i=0; i<number_of_classes; i++)
        for(int k=0; k<dimension_of_each_feature_vector; k++)
            largest_range_vector_for_class[i][k]=C[i][0][k];
    for(int i=0; i<number_of_classes; i++)
        for(int j=1; j<number_of_feature_vectors_in_class[i]; j++)
            for(int k=0; k<dimension_of_each_feature_vector; k++)
                if(C[i][j][k]>largest_range_vector_for_class[i][k])
                    largest_range_vector_for_class[i][k]=C[i][j][k];

我什至看不懂,但我确实明白了它的要点,基本上你创建了一个动态数组,一个 3D 动态数组,但是在你的程序中没有任何地方释放 3D 数组使用的内存,它看起来很泄漏,我无法为你删除,因为我无法阅读那个怪物......

【讨论】:

以上是关于多个文件的内存分配错误“在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用” [C ++]的主要内容,如果未能解决你的问题,请参考以下文章

错误:在文件 custom.f90 的第 463 行:内存分配失败

致命错误:接近堆限制的无效标记压缩分配失败 - 使用 fs 处理大文件时 JavaScript 堆内存不足

在 node.js 中使用 createWriteStream 创建大文件时 JavaScript 堆内存不足致命错误:达到堆限制分配失败

运行时错误:CUDA 内存不足。试图分配...但内存是空的

内存分配(malloc)的过程

malloc 函数的内存分配如何工作?