C++处理大量数据,在visual studio中编译运行时闪退,如何解决?

Qbop981001 2017-12-10 01:06:22
我的程序是读入一个400M的文本文件,统计其中的中文词词频,string全局变量数组开到了string[2500000],这个都没有问题。问题时在编译运行的时候,250M左右的数据还可以处理,再多的话在运行时直接闪退了,也没有任何提示,然而此时任务管理器中显示该程序占用的内存也就590多M,远小于我电脑的内存(我的电脑内存有8G),请问这是什么原因?如何解决?
先把代码贴到下面。
#include <iostream>
#include<fstream>
#include <cstdlib>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include<time.h>
#define MAXLINE 2500000
using namespace std;
string line[MAXLINE];
map<string, int> tMap;
vector<pair<string, int>> tVector;
pair<map<string, int>::iterator, bool> ret;
int cmp(const pair<string, int>& x, const pair<string, int>& y)
{
return x.second > y.second;
}
void oneword(string line[], int n)
{

int i,j,k,l; string word,temp;

for(i=0; i<n; i++){
for (j = 0; line[i][j]; j++)
;
k = j;
for (j = 0; j<k; ) {
temp = line[i][j];
temp += line[i][j + 1];
if (('0'-temp[0])<=128) {

word = temp;

ret = tMap.insert(make_pair(word, 1));
if (!ret.second)
++ret.first->second;
}
j = j + 2;
}
}

}
void sortMapByValue(map<string, int>& tMap, vector<pair<string, int> >& tVector)
{
for (map<string, int>::iterator curr = tMap.begin(); curr != tMap.end(); curr++)
tVector.push_back(make_pair(curr->first, curr->second));

sort(tVector.begin(), tVector.end(), cmp);
}
int main()
{
clock_t start = clock();
char str[2000];
char c;
char test[1];
test[0] = '\0';
int n, k, s;
ifstream infile("中文文本.txt");
if (!infile)
{
cout << "打开文件失败" << endl;
}
k = 0;
for (; ; ) {
s = 0;
n = 0;
for (; ; ) {
if (infile.eof()) { s = 1; break; }
else {
infile.get(c);

if (c == '\n') break;
else if (c >= 0 && c <= 127) continue;

else str[n++] = c;
}
}

str[n] = '\0';
if (strcmp(str, test) == 0)
;
else
{
int len;
len = strlen(str);

line[k] = str;
k++;
}
if (k == MAXLINE - 1) { cout << "超出数组范围" << endl; break; }
if (s == 1) break;
}
line[k] = test;
cout << k << endl;//输入文本文件中的数据

oneword(line, k);

sortMapByValue(tMap, tVector);
ofstream out;
out.open("1strings.txt");
for (int i = 0; i<tVector.size(); i++)
out << tVector[i].first << ": " << tVector[i].second << endl;
clock_t ends = clock();
cout << "Running Time : " << (double)(ends - start) / CLOCKS_PER_SEC << endl;
cout << "程序结束" << endl;
system("pause");
return 0;
}
...全文
735 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
棉猴 2017-12-30
  • 打赏
  • 举报
回复
引用 6 楼 wenpinglaoyao 的回复:
[quote=引用 4 楼 cfjtaishan 的回复:] 变量选择内存位置需要注意:栈大小<全局变量<堆(malloc/free, new/delete) 另外,如果要计算中文出现的频率,需要每个中文都先读到内存里吗?个人的建议是每次读出一个加入申请的缓存里,若读到已经在缓存里存在的不需要在放到缓存里而是直接让计数加1即可,这样如果中文词出现的频率较大时,可以减少很多的缓存,这样也不需要申请太大的缓存,可以在堆上申请空间,因为可以动态申请。保证内存不浪费
这位答主的回复可以考虑,参考象棋AI,每次象棋软件思考的时候,都是要把思考过的局面剪枝掉(比如你炮二平五,对手马8进7,你在马二进三,对手再卒7进1,这种局面思考过了,那么就不用再思考如下的棋谱:你先马二进三,对手马8进7,你再炮二平五,对手再卒7进1);象棋软件会把所有思考过的局面保存起来,思考一个新局面时,会看看这个局面前面是否已经考虑过了(有可能采用类似文件夹路劲的方法或者把局面看成一个大数字,然后用二叉查找比较大小的方法)。因为象棋的变化那么多,事先开辟所有局面的数组显然不可能[/quote] 同意这位朋友的意见,最好不要开一个那么大的数组,一来占资源,二来影响速度。也可以考虑使用Map
纹枰老妖 2017-12-29
  • 打赏
  • 举报
回复
引用 4 楼 cfjtaishan 的回复:
变量选择内存位置需要注意:栈大小<全局变量<堆(malloc/free, new/delete) 另外,如果要计算中文出现的频率,需要每个中文都先读到内存里吗?个人的建议是每次读出一个加入申请的缓存里,若读到已经在缓存里存在的不需要在放到缓存里而是直接让计数加1即可,这样如果中文词出现的频率较大时,可以减少很多的缓存,这样也不需要申请太大的缓存,可以在堆上申请空间,因为可以动态申请。保证内存不浪费
这位答主的回复可以考虑,参考象棋AI,每次象棋软件思考的时候,都是要把思考过的局面剪枝掉(比如你炮二平五,对手马8进7,你在马二进三,对手再卒7进1,这种局面思考过了,那么就不用再思考如下的棋谱:你先马二进三,对手马8进7,你再炮二平五,对手再卒7进1);象棋软件会把所有思考过的局面保存起来,思考一个新局面时,会看看这个局面前面是否已经考虑过了(有可能采用类似文件夹路劲的方法或者把局面看成一个大数字,然后用二叉查找比较大小的方法)。因为象棋的变化那么多,事先开辟所有局面的数组显然不可能
自信男孩 2017-12-19
  • 打赏
  • 举报
回复
引用 4 楼 cfjtaishan 的回复:
变量选择内存位置需要注意:栈大小<全局变量<堆(malloc/free, new/delete) 另外,如果要计算中文出现的频率,需要每个中文都先读到内存里吗?个人的建议是每次读出一个加入申请的缓存里,若读到已经在缓存里存在的不需要在放到缓存里而是直接让计数加1即可,这样如果中文词出现的频率较大时,可以减少很多的缓存,这样也不需要申请太大的缓存,可以在堆上申请空间,因为可以动态申请。保证内存不浪费
这种方法可以理解为:边读边处理;
自信男孩 2017-12-19
  • 打赏
  • 举报
回复
变量选择内存位置需要注意:栈大小<全局变量<堆(malloc/free, new/delete) 另外,如果要计算中文出现的频率,需要每个中文都先读到内存里吗?个人的建议是每次读出一个加入申请的缓存里,若读到已经在缓存里存在的不需要在放到缓存里而是直接让计数加1即可,这样如果中文词出现的频率较大时,可以减少很多的缓存,这样也不需要申请太大的缓存,可以在堆上申请空间,因为可以动态申请。保证内存不浪费
codedoctor 2017-12-18
  • 打赏
  • 举报
回复
因为你无论怎么开全局数组,栈的大小是被编译器限制了的,所以最好还是用new去使用堆内存生成动态数组
hongwenjun 2017-12-11
  • 打赏
  • 举报
回复
#define MAXLINE 2500000
string line[MAXLINE];
我觉得问题在这里。应该动态分配内存吧,或者使用 文件流
赵4老师 2017-12-11
  • 打赏
  • 举报
回复
容量大小从小到大:栈≤全局数据≤堆≤文件≤硬盘≤磁盘阵列≤云存储 当程序需要使用比如2GB~1TB左右的存储时,最简单的办法恐怕得是用文件读写模拟内存读写了吧。windows参考_fseeki64函数,linux参考fseeko64函数。
FILE *fA;fA=fopen("A","rb+");_fseeki64(fA,10000000000i64*sizeof(int),SEEK_SET);fputc(fA,0);//int A[10000000000];
int B;
_fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fread(&B,1,sizeof(int),fA);//B=A[9999999999];
_fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fwrite(&B,1,sizeof(int),fA);//A[9999999999]=B;
fclose(fA);

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧