🔒 Locked
Help allocating memory!!
Advertisement
Original Post
Please ima newbie and Im having this problem.
I need to allocate this:
cont=800;
d=(char(*)[150])malloc(cont*sizeof(char)*150);
that would be 800*150=150 Megabytes!!
when I run the program it crashes cos I don''t have enough memory..Im using an old compiler that I have here at school..its Borland C++ 3.0
Is there any way to get all that memory??..Can I use windows virtual memory??
Any help will be welcome.
Thanks
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
As the previous poster stated, that line allocated 120K which is no big deal at all, BUT you are using the wrong alloc (it is not a BUG, but it is less obvious than my suggestion).
You should use calloc, it is MADE to allocate memory for arrays of things, without as much chance for error ... a malloc prototype looks like:
void* malloc(int numBytes); // memory allocate
and is called like:
int numInts = 20;
int **myIntArray = (int**) malloc(numInts * sizeof(int));
calloc looks like:
void* calloc(int numElements, int elementSize); // continuous allocate
and is called like:
int numInts = 20;
int **myIntArray = (int**) calloc(numInts, sizeof(int));
now the above is just to help you use C/C++ better, but will not fix your current problem at all ...
I''m not sure your program crashes due to insufficient memory ... it might be crashing when you free() or delete the memory. Are you calling free?
Also, are you checking the malloc pointer for NULL, and if so ... IS IT NULL? You say it crashes, but do you mean it returns NULL? and perhaps your code tries to use NULL. If it is returning NULL, then you are right, it cannot allocate that much memory - but that is HIGHLY unlikely with 120K ... with 120MB that would be possible.
More info please.
You should use calloc, it is MADE to allocate memory for arrays of things, without as much chance for error ... a malloc prototype looks like:
void* malloc(int numBytes); // memory allocate
and is called like:
int numInts = 20;
int **myIntArray = (int**) malloc(numInts * sizeof(int));
calloc looks like:
void* calloc(int numElements, int elementSize); // continuous allocate
and is called like:
int numInts = 20;
int **myIntArray = (int**) calloc(numInts, sizeof(int));
now the above is just to help you use C/C++ better, but will not fix your current problem at all ...
I''m not sure your program crashes due to insufficient memory ... it might be crashing when you free() or delete the memory. Are you calling free?
Also, are you checking the malloc pointer for NULL, and if so ... IS IT NULL? You say it crashes, but do you mean it returns NULL? and perhaps your code tries to use NULL. If it is returning NULL, then you are right, it cannot allocate that much memory - but that is HIGHLY unlikely with 120K ... with 120MB that would be possible.
More info please.
Thank you Xai, you are right, i got confused, its 120K..dont know why I wrote 150MB..
and yes..I did this:
....
char (*d)[150];
...
cont=800;
if((d=(char(*)[150])malloc(cont*sizeof(char)*150))==NULL)
printf("Couldn´t allocate enough memory");
....
free(d);
I think that calloc and malloc both handles the memory the same way..I could be wrong though.
I dont know which is the problem..all the code is pretty simple and stupid..and it compiles great..but when executed the program just crashes.
I need this space cos I Need a pointer that points to 800 arrays of 150 characters each..
Cant detect the problem here..
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
and yes..I did this:
....
char (*d)[150];
...
cont=800;
if((d=(char(*)[150])malloc(cont*sizeof(char)*150))==NULL)
printf("Couldn´t allocate enough memory");
....
free(d);
I think that calloc and malloc both handles the memory the same way..I could be wrong though.
I dont know which is the problem..all the code is pretty simple and stupid..and it compiles great..but when executed the program just crashes.
I need this space cos I Need a pointer that points to 800 arrays of 150 characters each..
Cant detect the problem here..
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
Ok..this is the full code since its very very short:
The objective of the program is to take a txt file with 800 lines each one consisting of a video game name, then it must generate another file but with all the names sorted alphabetically...
I create the 800 arrays to hold the 800 titles(strings) and so I can sort them with a simple bubble method.
Please take a look and ignore the strange variable names and the comments since its in spanish..
Thanks:
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
[edited by - Stoffel on June 6, 2002 2:41:58 AM]
The objective of the program is to take a txt file with 800 lines each one consisting of a video game name, then it must generate another file but with all the names sorted alphabetically...
I create the 800 arrays to hold the 800 titles(strings) and so I can sort them with a simple bubble method.
Please take a look and ignore the strange variable names and the comments since its in spanish..
Thanks:
#include <stdio.h>
#include <conio.h>
#include <alloc.h>
#include <string.h>
#define n 120
int strcmp2(char *a,char *d) /*compara cadena d con a*/
{
for(;*a==*d;a++,d++)
if(*a=='\0')
return(0); /*son iguales*/
return(*a-*d); /*apenas sean distintos devuelve la resta de los caracteres*/
}
void cargarres(FILE *archi1, char (*d)[n])
{
char c;
int i=0;
archi1=fopen("dcreal.txt","r");
while(!feof(archi1))
{
fgets(d[i],n+1,archi1);
i++;
}
fclose(archi1);
}
void ordena(char (*d)[n],int cont)
{
int k,j,cota;
char aux[n];
cota=cont; /*son cont líneas para ordenar*/
k=1;
while(k!=0)
{
k=0;
for(j=0;j<cota;j++)
if(strcmp2(d[j],d[j+1])>0)
{
strcpy(aux,d[j]);
strcpy(d[j],d[j+1]);
strcpy(d[j+1],aux);
k=j;
}
cota=k;
}
}
void crearchi(char (*d)[n],FILE *archi2,int cont)
{
int i;
for(i=0;i<cont;i++)
fputs(d[i],archi2);
}
int main()
{
FILE *archi1,*archi2;
char (*d)[n]; /*puntero a arreglo con n columnas*/
int cont=0;
char c;
archi1=fopen("dcreal.txt","r");
while(!feof(archi1)) /*cuenta cantidad de líneas del texto*/
{
if(c=fgetc(archi1)=='\n')
cont++;
}
fclose(archi1);
printf("El texto tiene %d líneas", cont);
if((d=(char (*)[n])malloc(sizeof(char)*cont*n))==NULL) /*espacio para puntero que apunta a cont arreglos de 70 columnas*/
printf("No se pudo ubicar la memoria");
archi2=fopen("dcreal2.txt","w"); /*nuevo archivo ordenado*/
cargarres(archi1,d); /*cargo los arreglos auxiliares*/
ordena(d,cont); /*ordena los arreglos alfabéticamente por nombre del título*/
crearchi(d,archi2,cont);
fclose(archi2); /*escribo cont número de cadenas ya ordenadas en un nuevo archivo*/
free(d);
}
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
[edited by - Stoffel on June 6, 2002 2:41:58 AM]
There is a problem with the while loop that counts number of lines in a file:
It actually sets cont to the number of lines minus one.
At least when I changed
to
programs doesn''t crashed when it called free(d) like it did before.
int cont = 0;
...
while(!feof(archi1))
{
if(c = fgetc(archi1) == ''\n'')
cont++;
}
It actually sets cont to the number of lines minus one.
At least when I changed
d = (char (*)[n])malloc(sizeof(char) * cont * n)
to
d = (char (*)[n])malloc(sizeof(char) * (cont + 1) * n)
programs doesn''t crashed when it called free(d) like it did before.
Mhh...Im gonna check what you say,
It crashes when it calls free(d)?? I think it just crashes when it tries to allocate the memory.
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
It crashes when it calls free(d)?? I think it just crashes when it tries to allocate the memory.
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
Is Borland C++ 3.0 for DOS? I don''t remember right now if it''s forbidden to allocate more than 64KB of memory in DOS, due to the system''s 16-bits restrictions.
I suppose that''s the case, and the only way to fix it is to use some sort of paging. Allocate 64KB blocks, 120KB / 64KB = 1.875KB. One block that is 64KB big, the other 56KB. Then switch between those to access the whole memory.
I suppose that''s the case, and the only way to fix it is to use some sort of paging. Allocate 64KB blocks, 120KB / 64KB = 1.875KB. One block that is 64KB big, the other 56KB. Then switch between those to access the whole memory.
Borland C++ 3.0 or Borland C++Builder 3.0? BC3 is just a 16bit compiler that designed to run off Windows 3.11 while BCB3 is on 32bit. Most probably, as coelurus says, allocating >64K will have unpredicatble result.
Just guessing...
Since malloc() in 16bit accepts an unsigned int which is in range of 0-65535. Any larger will be wrapped... result in allocating the memory of (mod 65535) bytes (i guess).
That might be the reason it didn''t crash on IndirectX since (i guess again) maybe he uses 32bit compiler (eg. MSVC6++)
Just guessing...
Since malloc() in 16bit accepts an unsigned int which is in range of 0-65535. Any larger will be wrapped... result in allocating the memory of (mod 65535) bytes (i guess).
That might be the reason it didn''t crash on IndirectX since (i guess again) maybe he uses 32bit compiler (eg. MSVC6++)
and again... 16bit compiler/linker have an option to use Huge/Large/Compact/Medium/Small/Tiny memory model. Usually it is default on Small, which has 64K code, 64K data limit. Where as Large can have (practically) no more than 640K (the max size of conventional memory). ... just check it out in your compiler/linker option.
Try this one:
This compiles and runs using the GCC compiler. I made two changes:
1. In function ordena() changed
cota = cont;
to
cota = cont - 2;
2. In function main() changed
int cont = 0;
to
int cont = 1;
#include <stdio.h>
#include <string.h>
#define n 120
int strcmp2(char *a, char *d)
{
for(; *a == *d; a++, d++)
if(*a==''\0'')
return(0);
return(*a - *d);
}
void cargarres(FILE *archi1, char (*d)[n])
{
char c;
int i=0;
archi1=fopen("dcreal.txt","r");
while(!feof(archi1))
{
fgets(d[i],n+1,archi1);
i++;
}
fclose(archi1);
}
void ordena(char (*d)[n],int cont)
{
int k, j, cota;
char aux[n];
cota=cont - 2; //CHANGED
k=1;
while(k!=0)
{
k=0;
for(j=0;j<cota;j++)
if(strcmp2(d[j],d[j+1])>0)
{
strcpy(aux,d[j]);
strcpy(d[j],d[j+1]);
strcpy(d[j+1],aux);
k=j;
}
cota=k;
}
}
void crearchi(char (*d)[n],FILE *archi2,int cont)
{
int i;
for(i=0;i<cont;i++)
fputs(d[i],archi2);
}
int main()
{
FILE *archi1,*archi2;
char (*d)[n];
int cont=1; // CHANGED
char c;
archi1=fopen("dcreal.txt","r");
while(!feof(archi1))
{
if(c=fgetc(archi1)==''\n'')
cont++;
}
fclose(archi1);
printf("El texto tiene %d líneas", cont);
if((d=(char (*)[n])malloc(sizeof(char)*cont*n))==NULL)
printf("No se pudo ubicar la memoria");
archi2=fopen("dcreal2.txt","w");
cargarres(archi1,d);
ordena(d,cont);
crearchi(d,archi2,cont);
fclose(archi2);
free(d);
}
This compiles and runs using the GCC compiler. I made two changes:
1. In function ordena() changed
cota = cont;
to
cota = cont - 2;
2. In function main() changed
int cont = 0;
to
int cont = 1;
Ive been testing everything..and the program works ok..cos I tried to sort a txt file with only 6 lines..and it worked at it should....but when I try to sort my txt file with 800 lines of less than 80 chars each..it crashes...there are memory problems here...
I have tried with this *d[800] and allovate memory for each pointer..but the same happens..
I repeat..the compiler is for windows..thats still 16 bits??
BTW:how is paging used..where can I get info about it?
Thank people
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
I have tried with this *d[800] and allovate memory for each pointer..but the same happens..
I repeat..the compiler is for windows..thats still 16 bits??
BTW:how is paging used..where can I get info about it?
Thank people
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
I don''t know any doc about paging right now, so I''ll give you a little help:
Say you want to allocate 120KB. To be sure, divide it into 32KB blocks or something:
Allocate ''block'' 32KB blocks, plus a block that is ''lastBlock'' big. All pointers to these can be put into a nice array:
Now we got all memory allocated.
To use it, do this:
And something similar to get values. Hope I got it right...
Say you want to allocate 120KB. To be sure, divide it into 32KB blocks or something:
/* Find out how many full blocks to allocate */
blocks = length / 32768;
/* Find out whether we need a last block smaller than 32KB */
lastBlock = length % 32768;
Allocate ''block'' 32KB blocks, plus a block that is ''lastBlock'' big. All pointers to these can be put into a nice array:
/* Allow 10 blocks */
void *blockPointers[10];
/* Allocate full blocks */
for (i = 0; i < blocks; i++) blockPointers[i] = malloc(32768);
/* Allocate small block, if needed */
if (lastBlock > 0) blockPointers[i] = malloc(lastBlock);
Now we got all memory allocated.
To use it, do this:
void writeBlocks(int i, char val) {
int block = i / 32768,
index = i % 32768;
*(BlockPointers[block] + index) = val;
}
And something similar to get values. Hope I got it right...
Hey people, Thanks to everyone, I know about the different memory models, and I have tried
everything specially the large and compact models;
as I said, the program compiles perfectly and all, and it works when I has to sort txt´s
with a few lines, but it crashes with lots of them;
I tried to use farmalloc, it allocates memory in the far heap, but when I tru to compile
an error pops up, it says that function farmalloc should have a prototype, and that friends
is ridiculous, I have included the corresponding alloc.h header.
Should I use another compiler?..maybe MVC++..
Thanks coelurus..Im gonna try that as soon as I get home
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
everything specially the large and compact models;
as I said, the program compiles perfectly and all, and it works when I has to sort txt´s
with a few lines, but it crashes with lots of them;
I tried to use farmalloc, it allocates memory in the far heap, but when I tru to compile
an error pops up, it says that function farmalloc should have a prototype, and that friends
is ridiculous, I have included the corresponding alloc.h header.
Should I use another compiler?..maybe MVC++..
Thanks coelurus..Im gonna try that as soon as I get home
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
do this test:
make a file that will allocate JUST UNDER 64K of memory ... see if it runs ...
then add a line so it uses JUST OVER 64K memory ... see if it runs ...
tell us what you find.
ALSO ... I was not suggesting that you NEED to change to calloc, just saying it will make your code LOOK a little more obvious.
ALSO, please distinguish between CRASHING in malloc, and malloc FAILING ... CRASHING in malloc should NEVER happen, and would only happen if you do something not supported on your platform (i''m not sure what passing a negative size does, or what asking for more than 64K does on 16 bit architechture, but nothing else should CRASH malloc). FAILING in malloc is a normal thing ... meaning malloc returns NULL ... you say you have an "if" around your malloc and you printf if it succeeds of fails ... BUT YOU DONT TELL US WHICH HAPPENS...
so ... put a printf to see BOTH - IF it succeeds and ELSE it failed ... and you will get three options: a) malloc worked, b) malloc returned NULL, c) malloc crashed ... and tell us which happens
make a file that will allocate JUST UNDER 64K of memory ... see if it runs ...
then add a line so it uses JUST OVER 64K memory ... see if it runs ...
tell us what you find.
ALSO ... I was not suggesting that you NEED to change to calloc, just saying it will make your code LOOK a little more obvious.
ALSO, please distinguish between CRASHING in malloc, and malloc FAILING ... CRASHING in malloc should NEVER happen, and would only happen if you do something not supported on your platform (i''m not sure what passing a negative size does, or what asking for more than 64K does on 16 bit architechture, but nothing else should CRASH malloc). FAILING in malloc is a normal thing ... meaning malloc returns NULL ... you say you have an "if" around your malloc and you printf if it succeeds of fails ... BUT YOU DONT TELL US WHICH HAPPENS...
so ... put a printf to see BOTH - IF it succeeds and ELSE it failed ... and you will get three options: a) malloc worked, b) malloc returned NULL, c) malloc crashed ... and tell us which happens
Hi Xai, I have tested it that way and it wont crash when I must allocate less than 64k. And the program doesntfail, it just crashes,
I went with a different approach, as you said coeburus, I used this *d[799] until I understand
how paging is used as you explained me:
Here is the new code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <alloc.h>
#include <string.h>
#define n 120
#define m 799
int strcmp2(char *a,char *d) /*compara cadena d con a*/
{
for(;*a==*d;a++,d++)
if(*a==''\0'')
return(0); /*son iguales*/
return(*a-*d); /*apenas sean distintos devuelve la resta de los caracteres*/
}
void cargarres(FILE *archi1, char *d[m],int cont)
{
char c;
int i;
for(i=0;ifgets(d,n,archi1);
}
void ordena(char *d[m],int cont)
{
int k,j,cota;
char aux[n];
cota=cont-2; /*son cont líneas para ordenar*/
k=1;
while(k!=0)
{
k=0;
for(j=0;j if(strcmp2(d[j],d[j+1])>0) /*compara desde el caracter 16==nombre del titulo*/
{
strcpy(aux,d[j]);
strcpy(d[j],d[j+1]);
strcpy(d[j+1],aux);
k=j;
}
cota=k;
}
}
void crearchi(char *d[m],FILE *archi2,int cont)
{
int i;
for(i=0;ifputs(d[i],archi2); /*pongo 40 líneas en archi2*/
}
int main()
{
FILE *archi1;
FILE *archi2;
char *d[m]; /*puntero a arreglo con n columnas*/
int cont=1,i;
char c;
archi1=fopen("dcreal.txt","r");
archi2=fopen("dcreal2.txt","w"); /*nuevo archivo ordenado*/
while(!feof(archi1)) /*cuenta cantidad de líneas del texto*/
{
if(c=fgetc(archi1)==''\n'')
cont++;
}
fseek(archi1,0,SEEK_SET); /*vuelvo al comienzo del archivo*/
printf("El texto tiene %d líneas", cont);
for(i=0;iif(d[i]=(char *)malloc(sizeof(char)*n)==NULL) /*espacio para puntero que apunta a cont arreglos de 70 columnas*/
{
printf("No se pudo ubicar la memoria");
getchar();
}
cargarres(archi1,d,cont); /*cargo los arreglos auxiliares*/
ordena(d,cont); /*ordena los arreglos alfabéticamente por nombre del título*/
crearchi(d,archi2,cont);
for(i=0;ifree(d[i]);
fclose(archi1);
fclose(archi2); /*escribo cont número de cadenas ya ordenadas en un nuevo archivo*/
printf("Terminó de ordenar");
getchar();
}
I compiled and run the program again, with this other method, and now when it crashes one of those scary blue Windows window appear...hehehe..Strange indeed
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
I went with a different approach, as you said coeburus, I used this *d[799] until I understand
how paging is used as you explained me:
Here is the new code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <alloc.h>
#include <string.h>
#define n 120
#define m 799
int strcmp2(char *a,char *d) /*compara cadena d con a*/
{
for(;*a==*d;a++,d++)
if(*a==''\0'')
return(0); /*son iguales*/
return(*a-*d); /*apenas sean distintos devuelve la resta de los caracteres*/
}
void cargarres(FILE *archi1, char *d[m],int cont)
{
char c;
int i;
for(i=0;i
}
void ordena(char *d[m],int cont)
{
int k,j,cota;
char aux[n];
cota=cont-2; /*son cont líneas para ordenar*/
k=1;
while(k!=0)
{
k=0;
for(j=0;j
{
strcpy(aux,d[j]);
strcpy(d[j],d[j+1]);
strcpy(d[j+1],aux);
k=j;
}
cota=k;
}
}
void crearchi(char *d[m],FILE *archi2,int cont)
{
int i;
for(i=0;i
}
int main()
{
FILE *archi1;
FILE *archi2;
char *d[m]; /*puntero a arreglo con n columnas*/
int cont=1,i;
char c;
archi1=fopen("dcreal.txt","r");
archi2=fopen("dcreal2.txt","w"); /*nuevo archivo ordenado*/
while(!feof(archi1)) /*cuenta cantidad de líneas del texto*/
{
if(c=fgetc(archi1)==''\n'')
cont++;
}
fseek(archi1,0,SEEK_SET); /*vuelvo al comienzo del archivo*/
printf("El texto tiene %d líneas", cont);
for(i=0;i
{
printf("No se pudo ubicar la memoria");
getchar();
}
cargarres(archi1,d,cont); /*cargo los arreglos auxiliares*/
ordena(d,cont); /*ordena los arreglos alfabéticamente por nombre del título*/
crearchi(d,archi2,cont);
for(i=0;i
fclose(archi1);
fclose(archi2); /*escribo cont número de cadenas ya ordenadas en un nuevo archivo*/
printf("Terminó de ordenar");
getchar();
}
I compiled and run the program again, with this other method, and now when it crashes one of those scary blue Windows window appear...hehehe..Strange indeed
"Those who follow the path of the warrior must be ready to die, to stand for their convictions, live for one´s convictions, die for one´s convictions"
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement