1

I'am doing a homework on matrix multiplication. The problem that i want to find the largest matrix that i can handle (allocate). So i wrote the following code:

int n = 1;
while(1){
n++;
A=malloc(sizeof(double)*n*n);                                                                                                                           
B=malloc(sizeof(double)*n*n);
C=malloc(sizeof(double)*n*n);
if (C==NULL) {printf("Error No more size to allocate! n=%d\n",n); return 1;} 
// and the rest of the code including freeing the allocate

the result:

Error No more size to allocate! n=21785

Now i want to use another method: using A as the result instead of C. So that i only need 2(n**2)+n instead of 3(n**2).
So the new code should loke like this :

int n = 1;
while(1){
n++;
A=malloc(sizeof(double)*n*n);                                                                                                                           
B=malloc(sizeof(double)*n*n);
C=malloc(sizeof(double)*n);
if (C==NULL) {printf("Error No more size to allocate! n=%d\n",n); return 1;} 
// and the rest of the code including freeing the allocated space.

The problem that when i run this code it wont stop incrementing n but if i change the condition from (C==NULL) to (A==NULL||B==NULL||C==NULL) the result is:

Error No more size to allocate! n=21263

Any idea??

Edit
Do I cast the result of malloc? PS: My professor tell us to always use cast in malloc!!

Community
  • 1
  • 1
Chaker
  • 1,197
  • 9
  • 22
  • That's probably because in the second example you're allocating 2D arrays for A and B but only a 1D array for C. (Also, [don't cast the result of calls to `malloc()`.](http://stackoverflow.com/a/605858/1679849)) – r3mainer Mar 04 '15 at 22:04
  • 2
    really happy to see http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858 in every malloc related post. – Jason Hu Mar 04 '15 at 22:20
  • You just editd your post to make `C`'s allocation much larger... that will change the behaviour of running your program – M.M Mar 04 '15 at 22:30
  • 1
    also, how do you know "it wont stop incrementing n" ? – M.M Mar 04 '15 at 22:30
  • @MattMcNabb i don't mean that it won't stop incrementing n but what i mean is that n is too big comparing it with the result of the first code – Chaker Mar 04 '15 at 22:35
  • Output success/failure for every allocation and you will find out what is going on – M.M Mar 04 '15 at 22:56
  • Also post your real code, the stuff that is in the rest of the loop is relevant. – M.M Mar 04 '15 at 22:57

3 Answers3

1

Your program fails to allocate A or B long before it fails to allocate C, which is much smaller. With n being approximately 21263, n*n is 21263 times larger than n. The loop will continue for about 10000 repetitions. If you free C after successful allocation, the loop will even continue for a few hundred million repetitions until n reaches about 21263*21263. You just have to wait long enough for your program to exit.

  • I understand that but the problem is that when trying to run the second code an check for the three matrix a got a smaller result than the first code. in the case i should obtain a grater result?? – Chaker Mar 04 '15 at 22:48
  • The amount of free memory varies. On multitasking systems, other processes may take up more or less memory depending on the exact moment in time when you check. – Leonard Michlmayr Mar 04 '15 at 23:33
0
there are a few things to note

1) the main consideration is that memory, once allocated (by malloc and not free'd) means the amount of available heap to allocate goes down, even as 'n' goes up.

2) any call to malloc() can fail, including the first call
   this means the failure could be any of the calls to malloc()

3) in C, the returned value from malloc (and family) should not be cast.

4) the returned value from malloc() should always be checked, 
   not just one in three calls to malloc()

regarding the posted code. 
1) all the above considerations should be implemented
2) in the second example of posted code, just because a 
   larger memory request (n*n) fails  does not mean a 
   smaller request (n) would fail.
   that is why the modification catches the failure of 'A'

3) the heap address and the size of the heap are normally 
   available at compile time, so there is no need
   for the kind of code you posted
user3629249
  • 16,402
  • 1
  • 16
  • 17
  • for the first note i'am freeing the allocated memory. But i don't understand the last note about the heap. Doesn't the OS provide more memory if the heap is full?? – Chaker Mar 04 '15 at 22:17
0

You could try doing a single allocation, then assigning pointers for B and C as offsets from A. Rather than starting at a small value, start at a large value that should fail on the first loops, so that when the allocation does succeed, the heap will not be fragmented.

rcgldr
  • 27,407
  • 3
  • 36
  • 61