C内存分配:为什么没有足够的内存(仅250K) [英] C Memory Allocation: Why there is not enough memory(250K only)
问题描述
我无法弄清楚我的.c代码无法分配〜250K内存的原因.这是分配代码:
I am having trouble figuring out the reason why my .c code is having trouble allocating ~250K of memory. Here is the allocation code:
struct IMAGE {
int width, height, maxval;
char **data;
};
void raiseError(char *msg)
{
printf("%s", msg);
getch();
exit(1);
}
//...
IMAGE readPGM()
{
IMAGE image;
image.data = (char **) malloc(sizeof(char)*image.height);
//..
for (i=0; i<image.height; i++) {
image.data[i] = (char *) malloc(sizeof(char)*image.width);
if (image.data[i]=='\0') {
printf("%d\n", i);
raiseError("Not enough memory!..");
}
}
//..
}
//..
当i = 116时程序退出. image.width和image.height在这里等于500,所以我想在这里分配500x500 = 250000字节.但是最多分配了116x500 = 58000字节.那么,有什么限制吗?我的代码有问题吗?我在下面发布了完整的源代码,以防万一.这个想法是将一个PGM文件读入IMAGE结构,对其进行处理,然后将其重写到另一个文件中.如您所知,由于我无法找出分配更多内存的方法,因此它尚未完成.
The program exits when i=116. image.width and image.height equals to 500 here, so I want 500x500=250000 bytes to be allocated here. But 116x500 = 58000 bytes are being allocated at maximum. So, is there something that limits it? Is there something wrong with my code? I am posting the full source below, just in case if it is necesarry. The idea is to read a PGM file into the structure IMAGE, process it and rewrite it in another file. As you can tell, it is not complete yet because I couldn't figure out a way to allocate more memory.
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<alloc.h>
struct IMAGE {
int width, height, maxval;
char **data;
};
void raiseError(char *msg)
{
printf("%s", msg);
getch();
exit(1);
}
char *toString(int num)
{
char sign = 0;
if (num<0) {
sign = -1;
num*=-1;
}
int numLen = 1;
if (sign<0) {
numLen++;
}
int tmpNum = num;
while (tmpNum>9) {
tmpNum /= 10;
numLen++;
}
char *result = (char *)malloc(sizeof(char)*(numLen+1));
result[numLen] = '\0';
char ch;
while (num>9) {
ch = (num%10)+'0';
num /= 10;
result[numLen-1] = ch;
numLen--;
}
result[numLen-1] = num + '0';
if (sign<0)
result[0] = '-';
return result;
}
int toInteger(char *line)
{
int i=strlen(line)-1;
int factor = 1;
int result = 0;
while (i>=0) {
result += factor*(line[i]-'0');
factor *= 10;
i--;
}
return result;
}
char *getNewParam(FILE *fp)
{
char ch = 'X';
char *newParam;
newParam = (char*) malloc(1);
newParam[0] = '\0';
int paramSize = 0;
while (!isspace(ch)) {
ch = fgetc(fp);
if (!isspace(ch)) {
if (ch=='#') {
while (fgetc(fp)!='\n');
continue;
}
paramSize++;
newParam = (char *) realloc(newParam, paramSize+1);
newParam[paramSize-1] = ch;
}
}
newParam[paramSize] = '\0';
return newParam;
}
IMAGE readPGM()
{
FILE *fp;
IMAGE image;
//Open the file.
fp = fopen("seeds2.pgm","r+b");
if (fp=='\0')
raiseError("File could not be opened!..");
//Check if it is a raw PGM(P5)
char *line;
line = getNewParam(fp);
if (strcmp(line, "P5")!=0)
raiseError("File is not a valid raw PGM(P5)");
int paramCount = 0;
int *pgmParams;
pgmParams = (int *)malloc(sizeof(int)*3);
while (paramCount<3) {
line = getNewParam(fp);
pgmParams[paramCount++] = toInteger(line);
}
int pixelSize;
if (pgmParams[2]>255)
pixelSize = 2;
else
pixelSize = 1;
image.width =pgmParams[0];
image.height =pgmParams[1];
image.maxval =pgmParams[2];
free(pgmParams);
image.data = (char **) malloc(sizeof(char)*image.height);
int i,j;
long sum = 0;
for (i=0; i<image.height; i++) {
image.data[i] = (char *) malloc(sizeof(char)*image.width);
sum += sizeof(char)*image.width;
if (image.data[i]=='\0') {
printf("%d\n", i);
raiseError("Not enough memory!..");
}
}
for (i=0; i<image.height; i++) {
for (j=0; j<image.width; j++) {
fread(&image.data[i][j], sizeof(char), image.width, fp);
}
}
fclose(fp);
return image;
}
void savePGM(IMAGE image)
{
FILE *fp = fopen("yeni.pgm", "w+b");
fprintf(fp, "P5\n%s\n%s\n%s\n",
toString(image.width), toString(image.height), toString(image.maxval));
int i,j;
for (i=0; i<image.height; i++) {
for (j=0; j<image.width; j++) {
fwrite(&image.data[i][j], sizeof(char), 1, fp);
}
}
fclose(fp);
}
int main()
{
clrscr();
IMAGE image = readPGM();
//process
savePGM(image);
getch();
return 0;
}
推荐答案
问题的答案在您添加的注释中.您正在使用(古董)16位x86实模式编译器.一个16位虚拟机总共只能寻址1Mb的内存,通常程序只能访问其中的640Kb,并且与OS共享.
The answer to your question is in the comment you added to it. You are using an (antique) 16 bit x86 real mode compiler. A 16 bit virtual machine can address only 1Mb of memory in total, only 640Kb of which is normally accessible to programs, and is shared with the OS.
[根据paxdiablo的评论进行编辑]
除了这些限制之外,分段寻址架构还引发了许多内存模型,其中特定内存区域的限制可能只有64kb.
Further to those restrictions the segmented addressing architecture also gives rise to a number of memory models where as little as 64kb may be the limit for specific memory areas.
另外,malloc()的参数的类型为size_t,在这种情况下,它只能是16位-您应该检查一下.我记得使用一个名为halloc()的变体进行大型分配.但是缺少DOS扩展器,仍然有640kb的限制.
Also the argument to malloc() has type size_t, which may only be 16-bit in this case - you should check. I recall using a variant called halloc() for large allocations. But short of using a DOS extender, there is still a 640kb limit.
[结束编辑]
有许多更好和免费的现代32位编译器可用.丢弃古董.我建议 VC ++ Express Edition
There are a number of far better and free modern 32-bit compilers available. Dump the antique. I suggest VC++ Express Edition
除此以外:
if(image.data[i]=='\0')
应该是
if(image.data[i]==0)
或
if(image.data[i]==NULL)
碰巧它在两种情况下都可以使用,但是从技术上讲,您正在测试的是空指针而不是NUL字符.
As it happens it will work in either case, but technically you are testing for a null-pointer not a NUL character.
这篇关于C内存分配:为什么没有足够的内存(仅250K)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!