Archived

This topic is now archived and is closed to further replies.

Help allocating memory!!

This topic is 5661 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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"

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Tai-Pan
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"


Should this be:
int cont = 800;
char * d = (char *)malloc(cont * sizeof(char) * 150);

It allocates 1 * 800 * 500 = 400000 bytes/120 KB.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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"

Share this post


Link to post
Share on other sites
quote:
Original post by Tai-Pan
I need this space cos I Need a pointer that points to 800 arrays of 150 characters each..


800 arrays of 150 characters each is not the same as one array of 800*150 characters. How are you using this data?

Share this post


Link to post
Share on other sites
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:


  
#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]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I always thought the c in calloc() stood for "clear" as it also sets the memory to 0. And since the memory it allocates is perfectly fine for anything (not just arrays), it stuck in me head.

Go fig.

Share this post


Link to post
Share on other sites
There is a problem with the while loop that counts number of lines in a file:

  
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.

Share this post


Link to post
Share on other sites
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"

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Thats the strange thing about this..Im using Borland C++ 3.0 for Windows..not the Dos version..hehe..any clue??

"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"

Share this post


Link to post
Share on other sites
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++)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Try this one:

  
#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;

Share this post


Link to post
Share on other sites
It seems you want to allocate 800 150bytes arrays, or vice versa. You can use an array with 800 pointers and allocate 150bytes arrays to each entry, if you don''t want to use a paging system. That should work with 16-bits compilers.

Share this post


Link to post
Share on other sites
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"

Share this post


Link to post
Share on other sites
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:


  
/* 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...

Share this post


Link to post
Share on other sites
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"

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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"

Share this post


Link to post
Share on other sites
I confirm it, I tried to allocate space for less than 64k and it doesnt crash..But then I added many more char lines and when it exceeds the 64k limit..the program crashes..
I verified with an if statement if malloc returned NULL..and thats not the problem..the malloc just crashes..
So...I have tried the huge memory model and everything..what should I do?..Use a newer compiler?..Is there any other way??

"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"

Share this post


Link to post
Share on other sites
If you could get a new compiler, great. But you should be able to allocate big hunks of memory, since 16-bits Z-buffers in DOS need 128KB of memory. Try to make an array with 4 entries or such, and manually allocate 40KB to each entry. If that fails, I don''t know what''s wrong...

Share this post


Link to post
Share on other sites
I understand how paging works now, but how can I implement the char arrays that I need inside the memory allocated in each entry of the memory array?

"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"

Share this post


Link to post
Share on other sites