user-0 提问: 系统剩余的内存超过4G，realloc大约100多M内存还会失败吗？

回复:
user: user-1
content: 内存不够用的终极解决方法是： 用文件读写模拟内存读写

user: user-2
content: 程序启动的时候，就把内存申请足够，然后就不要释放了，否则内存碎片化之后，很难再申请大块内存。

user: user-0
content: 谢谢楼上各位，尤其是jha334201553、mLee79等人。  现将楼上答案做一个简要总结：  问题：32位Win7，4G内存。程序已经占用1.2G内存，还剩大约1G。再用realloc申请100多M的内存，失败。 换到64位Win7上，8G内存。在同一个地方出错。此时系统还剩至少4G内存。 如果没有足够多的【连续】内存供realloc用，它就会出错，即使总的内存还够用。但问题是，剩余这4G多内存，就没有100多M连续的吗？  解答：在64位系统下，程序还是32位的啊，程序指针最大值也就是0xFFFFFFFF，而系统又规定高2G保留系统使用，最大寻址就是0x7FFFFFFF，不能申请超过2G的内存。  解决方法1：按照微软规定修改启动项到最大，可以使程序用的内存达到3G 解决方法2：在64位系统下, 打开 /LARGEADDRESSAWARE 选项, 32位程序可以使用4G内存 解决方法3：把程序编译成64位的，这才是一劳永逸的方法 另外，程序启动时，最好一次申请足够的内存，避免频繁地申请  方法1：  xp系统修改boot.int ： multi(0)disk(0)rdisk(0)partition(4)\WINDOWS="Microsoft Windows XP Professional" /3GB /fastdetect 加上那个/3G 就可以  win7 系统用 bcdedit.exe ： BCDEdit /set increaseuserva 3072  （来自http://bbs.csdn.net/topics/390615068） 注：用BCDEdit命令时，可能需要管理员权限。 解决方法： 　　1、点击”开始“菜单; 　　2、然后输入”cmd“; 　　3、在出现的”cmd.exe“程序中右键单击，选择”以管理员身份运行“，就得到一个具有管理员权限的命令行窗口，然后再运行bcdedit.exe就OK。 （来自http://www.pcyyjs.com/sys/win7/3853/）  方法2：    方法3  VS 2008的64位编译环境的安装和使用：详见http://blog.csdn.net/clever101/article/details/8844314  如果程序中用到了lib、dll文件，则要重新把它们编译成64位的，否则会报错：模块计算机类型“X86”与目标计算机类型“x64”冲突 如果还报错，参见： http://blog.csdn.net/txh0001/article/details/7019052 http://blog.csdn.net/qtbmp/article/details/7273191

user: user-3
content: 如果系统中没有那么大的连续内存空间, 分配失败也是正常的.  这就是常说的"内存碎片"问题. 虽然可用内存很多, 但是可能你想申请的那么大的连续内存却已经没有了.

user: user-1
content: 内存不够用的终极解决方法是： 用文件读写模拟内存读写 或者 直接用操作系统提供的内存映射文件API

user: user-4
content: xp的话修改boot.int  multi(0)disk(0)rdisk(0)partition(4)\WINDOWS="Microsoft Windows XP Professional" /3GB /fastdetect 加上那个/3G 就可以  win7 的话要用 bcdedit.exe  BCDEdit /set increaseuserva 3072

user: user-5
content: 直接用系统调用分配页呢

user: user-6
content: 并不是系统64位，应用程序就是64位。这是两个概念

user: user-6
content: 你得把程序编译为64位程序，才能使用大于2g以上内存。

user: user-0
content: 引用 12 楼 jha334201553 的回复:引用 11 楼 bukeshuo8 的回复:是的。我不明白的是，放到64位系统下，在剩余内存大于4G的情况下，为什么没有100多M的连续内存，来供realloc使用？在64位系统下，你程序还是32位的啊，你程序指针最大值也就是0xFFFFFFFF，而系统又规定高2G保留系统使用，那么你最大寻址不就是0x7FFFFFFF么，你如何申请超过2G的内存？ 原来如此！ 那么，怎样按照微软规定修改启动项为3G呢？ 当然，一劳永逸的方法是把我的程序变成64位的，如何才能办到呢？

user: user-4
content: 引用 9 楼 bukeshuo8 的回复:32位系统能寻址2^32B=4GB内存。但实际中，会有一些地址为其他地方所用。所以实际中，32位系统下，最大能利用3G多的内存。默认2G-4G的内存是系统用的，驱动、系统内核在使用，你使用一个指针操作2G以上内存立马挂掉。并非程序是能用4G，你按照微软规定修改启动项最大用户才3G

user: user-4
content: 引用 11 楼 bukeshuo8 的回复:是的。我不明白的是，放到64位系统下，在剩余内存大于4G的情况下，为什么没有100多M的连续内存，来供realloc使用？在64位系统下，你程序还是32位的啊，你程序指针最大值也就是0xFFFFFFFF，而系统又规定高2G保留系统使用，那么你最大寻址不就是0x7FFFFFFF么，你如何申请超过2G的内存？

user: user-0
content: 引用 8 楼 jha334201553 的回复:你没理解，系统内存，程序寻址空间，内存寻址，这些基本的概念。你把程序编译成x64的然后在x64上运行可以申请超过4G的内存了。而编译成x86的最大最大也就能寻址3G，一般是2G，地址从0x10000~0x7ffeffff,还要出去exe、dll、一些结构体PEB  占用的内存，能申请到1.5G就非常非常好了 是的。我不明白的是，放到64位系统下，在剩余内存大于4G的情况下，为什么没有100多M的连续内存，来供realloc使用？

user: user-0
content: 引用 7 楼 u011779875 的回复:[quote=引用 3 楼 bukeshuo8 的回复:] [quote=引用 2 楼 u011779875 的回复:]  我感觉你没明白realloc函数 realloc 有一个问题 你要知道就是它在realloc的时候 会出现连续空间不够的情况 之后把以前的申请的内存释放掉 在重新申请一片空间 所以你要用的是realloc的返回值 而不是说你realloc 它就会成功。 用realloc的时候一定要小心的检查。 在有就是你需要看C标准库是如何实现realloc 它的陷阱在哪。 realloc返回结果是NULL。剩余4G内存，为什么还不够realloc 100多M的呢？[/quote] 你不贴代码 是看不出问题的 你是不是连怎么用都写错了啊  [/quote]   const  Coord_Mat_double operator*(const Coord_Mat_double& A, const Coord_Mat_double &B) { 	//A: m * l, B:	l2*n. C=A*B：m*n 	int m=A.dim(0),l=A.dim(1), l2=B.dim(0), n=B.dim(1); 	if(l!=l2) 	{ 		MessageBoxA(NULL,"Matirx multiply error! Matrix demensions don't match.",NULL,MB_OK); 		return A; 	}  	int i,j,k,q;  	int nA=A.NumNonzeros(); 	int nB=B.NumNonzeros();  	 	if(!nA) 		return A;//A为0 	if(!nB) 		return B;//B为0 	 	 	int *num= new int[l];//B的每一行非0元素的个数 	for(i=0;i<l;i++) 		num[i]=0; 	for(i=0;i<nB;i++) 	{ 		j=B.row_ind(i); 		num[j]++; 	}  	int *row_ptrB=new int[l+1];//B的每一行非0元素在B.val[]中的位置（最后一个当监视哨） 	row_ptrB[0]=0; 	for(i=1;i<=l;i++) 	{ 		row_ptrB[i]=row_ptrB[i-1]+num[i-1]; 	}  	int nC=0;//当前C 中非零元素的个数 	int pA=0;//指示A.data 中当前非零元素的位置  	int memSize=0.01*m*n+10*m+10*n+100;//当前申请的内存空间。估计用这个会比较合适  	int* row=(int*)malloc(sizeof(int)*memSize); 	int* col=(int*)malloc(sizeof(int)*memSize); 	double* val=(double*)malloc(sizeof(double)*memSize);  	if(!row || !col || !val) 	{ 		MessageBoxA(NULL,"Malloc error in matrix multiply.",NULL,MB_OK); 		return A; 	}  	double *temp=new double[n]; 		 	for ( i= 0;i<m; i++) 	{   		for (j=0;j<n;j++)  			temp[j]=0; /*cij 的累加器初始化*/  		//while (A.row_ind(pA)==i ) /*求第i 行的*/ 		while (pA<nA&&A.row_ind(pA)==i )//2013.06.20 hyb 又找出一个bug!!! 		{  			k=A.col_ind(pA); /*A 中当前非零元的列号*/  			for (q=row_ptrB[k]; q<row_ptrB[k+1]; q++) /* B 中第k 行的每一个非零元素*/ 			{  				j=B.col_ind(q); 				temp[j]+=A.val(pA)* B.val(q); 			} 			pA++; 		}   	for (j=0;j<n;j++) 		if (temp[j]!=0) 		{  			nC++; 			if(nC>memSize)//当前数组空间不够用了 			{ 				memSize *= 2;//申请空间加倍  				int* row2=(int*)realloc(row, sizeof(int)*memSize); 				int* col2=(int*)realloc(col, sizeof(int)*memSize); 				double* val2=(double*)realloc(val, sizeof(double)*memSize);//不能直接把值返回给val，以防出现特殊情况 				/*1.如果 当前连续内存块足够 realloc 的话，只是将p所指向的空间扩大，并返回p的指针地址。 这个时候 q 和 p 指向的地址是一样的。 				2.如果 当前连续内存块不够长度，再找一个足够长的地方，分配一块新的内存q，并将 p指向的内容 copy到 q，返回 q。并将p所指向的内存空间删除。 				*/ 				if(!row2 || !col2 || !val2) 				{ 					MessageBoxA(NULL,"Realloc error in matrix multiply.",NULL,MB_OK); 					ofstream outfile("D:\\coord_double_error.txt",ios::app); 					outfile<<"realloc memory: "<<memSize<<" *(int + int + double)。 m= "<<m<<"	n=: "<<n<<endl; 					outfile.close(); 					return A; 				}  				row=row2; 				col=col2; 				val=val2; 			} 			row[nC-1]=i; 			col[nC-1]=j; 			val[nC-1]=temp[j]; 		} 	}  	 	Coord_Mat_double C=Coord_Mat_double(m,n,nC,val,row,col);  	free(row); 	free(col); 	free(val); 	delete []num; 	delete []row_ptrB; 	delete []temp;  	return C; 	 }   是稀疏矩阵的乘法。由于矩阵大小、相乘结果中非0元的个数不确定，所以没办法事先确定一定要申请多少内存。只能先申请一个初始值，不够再加倍。

user: user-0
content: 引用 5 楼 jha334201553 的回复:你这是神马问题，程序已经占用1.2G，系统剩余1G。。。。 程序不管系统剩余多少，只要你里面的地址空间还够就可以申请（理论），但是如果地址空间都没用用完了就没办法了，32位程序最大寻找也就2G，你那剩余系统空间根本没有意义，如果你电脑只有256M内存，那32为程序还是可以寻址2G的，只是用了虚拟内存映射到磁盘的pagefile里面，你想多用些地址空间，建议你开机3G选项，用户可以使用3G的地址空间。。。 32位系统能寻址2^32B=4GB内存。但实际中，会有一些地址为其他地方所用。所以实际中，32位系统下，最大能利用3G多的内存。

user: user-4
content: 你没理解，系统内存，程序寻址空间，内存寻址，这些基本的概念。你把程序编译成x64的然后在x64上运行可以申请超过4G的内存了。而编译成x86的最大最大也就能寻址3G，一般是2G，地址从0x10000~0x7ffeffff,还要出去exe、dll、一些结构体PEB  占用的内存，能申请到1.5G就非常非常好了

user: user-7
content: 引用 3 楼 bukeshuo8 的回复:[quote=引用 2 楼 u011779875 的回复:]  我感觉你没明白realloc函数 realloc 有一个问题 你要知道就是它在realloc的时候 会出现连续空间不够的情况 之后把以前的申请的内存释放掉 在重新申请一片空间 所以你要用的是realloc的返回值 而不是说你realloc 它就会成功。 用realloc的时候一定要小心的检查。 在有就是你需要看C标准库是如何实现realloc 它的陷阱在哪。 realloc返回结果是NULL。剩余4G内存，为什么还不够realloc 100多M的呢？[/quote] 你不贴代码 是看不出问题的 你是不是连怎么用都写错了啊

user: user-8
content: 大块的内存要在程序开始的时候就申请，而且别释放。随着程序的运行过程中内存的不断申请和释放，内存可能被碎片化了，无法再申请出大块连续的内存

user: user-4
content: 你这是神马问题，程序已经占用1.2G，系统剩余1G。。。。 程序不管系统剩余多少，只要你里面的地址空间还够就可以申请（理论），但是如果地址空间都没用用完了就没办法了，32位程序最大寻找也就2G，你那剩余系统空间根本没有意义，如果你电脑只有256M内存，那32为程序还是可以寻址2G的，只是用了虚拟内存映射到磁盘的pagefile里面，你想多用些地址空间，建议你开机3G选项，用户可以使用3G的地址空间。。。

user: user-0
content: 引用 1 楼 fishion 的回复:是不是其它地方导致出错了，你直接申请大内存看看 我是先melloc一定大小的空间（比如10M），计算过程中，不够用，再把这个空间加倍（用realloc）。这样，加倍到申请100多M的时候，就realloc失败了。