univers1314 2024-10-05 11:02 采纳率: 33.3%
浏览 6
已结题

string buf 爆内存的问题

爆内存的问题
while (getline(file, line))读一个几十MB的记事本,再放到
string buf_A[4098]表里,一直循环读,会爆内存。读完后要怎样才能释放内存。
https://img-mid.csdnimg.cn/release/static/image/mid/ask/c2e6e63d86ea4c949043f20c645b2f43.png
代码如下:

#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <string.h>
#include <time.h>
#include "windows.h"
#include <direct.h>
#include <sys/stat.h>

using namespace std;

//******************************************定义全局变量***********************************************//

string buf_A[4098];                //写数据表缓冲x*6        1024*4+2=4096+2=4098    表B大空间可以大大增加命中率

char i = 0;
int bufB_num = 0;                    //单数总和
long int all_num = 0;                //总数
long int vaild_files = 0;            //有效文件

//*****************************************************************************************************************************************//
void Exedat()    //查检路径打开文件在不在+处理数据
{
    char* logpath = "C:\\Users\\work\\Documents\\visual studio 2017\\Projects\\ConsoleApplication1\\Debug\\09.log";
    ofstream outfile;
    outfile.open(logpath, ios::out | ios::app);

    fstream file("D:\\Desktop VS\\新建文件夹\\00A-37MB.txt", ios::in);
    if (!file)
    {
        cout << "Sorry Failed to open file!" << endl;
        file.close();        //关闭读文件流
        system("pause");
        exit(0);            //直接结束
    }
    cout << "scaning . . . dat please waiting . . . !" << endl;         //显示一下开始扫描
    string line;
    int countA = 0;

    while (getline(file, line))
    {
        buf_A[countA] = line;
        all_num++;
        countA++;    

        if (countA >= 4096)        //表A上限4098    如果超值清空数组
            {
            countA = 0;                        //清零
            memset(buf_A, 0, sizeof(buf_A)); // 清空数组将数组所有元素赋值为0,需要引入string.h头文件
            }
    }
    outfile.close();    //关闭写文件流
//******************************输出************************************//
    cout << "all line count = " << "< " << all_num << " >" << endl;
    cout << "filter file count = " << "< " << vaild_files << " >" << endl;
    //*********************清空数组***********************//
    countA = 0;
    memset(buf_A, 0, sizeof(buf_A)); // 清空数组将数组所有元素赋值为0,需要引入string.h头文件

    all_num = 0;                    //只能在下面清空总数
    vaild_files = 0;
    line = "";
    //****************************************************//
    file.close();    //关闭读文件流
}
//************************************************************************************************//
int main()
{
    while (1)
    {
        Exedat();
        system("pause");
    }
}

![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/d69d5f7bfad041d5beb3ffbd3538d3fd.png "#left")


  • 写回答

2条回答 默认 最新

  • 一轮明月照丘壑 2024-10-05 11:03
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    你在循环读取文件时使用了固定大小的数组 buf_A 来存储每一行的数据。当文件大小超过数组 buf_A 的容量时,你尝试清空数组以继续读取文件,但是这种做法是不正确的。你的数组的大小是固定的,并且无法释放内存。随着你的循环持续进行,数组的大小会一直占用内存空间,并且当文件过大时会导致内存溢出。解决这个问题的一个方法是使用动态分配的内存来存储数据,并在不再需要这些数据时释放内存。你可以使用 std::vector 来解决这个问题。以下是一个简单的例子来展示如何使用 std::vector 来读取大文件并释放内存:

    首先,你需要引入 <vector> 头文件。然后,你可以使用 std::vector<std::string> 来代替 string buf_A[] 来存储数据。这样你可以动态地增加或减少存储空间的容量。当你不再需要数据时,你可以简单地清空向量来释放内存。这是一个简单的例子:

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    void Exedat() {
        // ... 其他代码保持不变 ...
        vector<string> buf_A; // 使用 vector 来存储数据
        // ... 其他代码保持不变 ...
        while (getline(file, line)) {
            buf_A.push_back(line); // 将数据添加到向量中
            // ... 其他代码保持不变 ...
        }
        // ... 其他代码保持不变 ...
    }
    // ... 其他代码保持不变 ...
    

    buf_A 不再需要时(在你的例子中是在每次循环结束时),你可以简单地清空向量来释放内存:buf_A.clear()。这样你就可以避免内存溢出的问题了。如果你想要限制向量的容量,你可以在达到某个阈值时清空并重新分配向量的一部分来节省内存。但请注意,频繁的重新分配可能会导致性能下降,所以请根据你的具体需求进行权衡。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 10月15日
  • 已采纳回答 10月7日
  • 修改了问题 10月5日
  • 修改了问题 10月5日
  • 展开全部