Products > Programming

Memory error in C program (SOLVED)

(1/3) > >>

Picuino:
I was trying to compare speeds between 2 programs in C and in Python.
The program in C gives me a memory error when malloc() is greather than 33000 bytes.

Can anyone help me?
I was trying to compile with Borland C++ command line and with TinyC compiler (both raise an error)


--- Code: (C) ---#include <stdlib.h>
#include <stdio.h>
#include <time.h>

char *eratosthenes(long n) {
   char *nums, *p;
   long i, x;

   /* Initialize */
   nums = malloc(n+1);
   p = nums;
   *p++ = 0;
   *p++ = 0;
   for(i=2; i<=n; i++)
      *p++ = 1;
   
   /* Find primes */
   for(i=2; i<=n; i++) {
      if(nums[i] == 1) {
         x = i*i;
         while(x<=n) {
            nums[x] = 0;
            x += i;
         }
      }
   }
   return nums;
}

int main() {
   char *nums;
   int i;
   clock_t timeit;
   float t_total;
   
   timeit = clock();
   for(i=0; i<1000; i++) {
      nums = eratosthenes(100000);
      free(nums);
   }
   timeit = clock() - timeit;
   t_total = (float)(timeit) / CLOCKS_PER_SEC;
   printf("time = %f\n", t_total);
}
--- End code ---

The program works fine with eratosthenes(10000) and raise memory error with eratosthenes(100000)

Nusa:
Good practice to check to see if a malloc succeeded. That'll eliminate the run-time error.


--- Code: ---nums = malloc(n+1);
if (!nums){ // malloc failed
   return NULL;
}

--- End code ---

It would appear that 32K (2**15) is likely the limit for malloc() in your environment or using those compilers.

Andy Watson:
What is the size of the long int on your system? If it is four bytes, you might be running into problems when you square i (x = i * I). If the value returned for x is greater than maximum for a signed long int, it can wrap-araound and become negative. If this happens, the test " x <=  n" is going to return true.

Picuino:
Thanks, that is the problem.

running program:


--- Code: (c) ---#include <stdlib.h>
#include <stdio.h>
#include <time.h>

char *eratosthenes(unsigned long n) {
   char *nums, *p;
   unsigned long i, x;

   /* Initialize */
   nums = malloc(n+1);
   p = nums;
   *p++ = 0;
   *p++ = 0;
   for(i=2; i<=n; i++)
      *p++ = 1;

   /* Find primes */
   for(i=2; i<=n; i++) {
      if(nums[i] == 1) {
         x = i*i;
         if (x > n)
            break;
         while(x<=n) {
            nums[x] = 0;
            x += i;
         }
      }
   }
   return nums;
}

int main() {
   char *nums;
   int i;
   clock_t timeit;
   float t_total;
   
   timeit = clock();
   for(i=0; i<100; i++) {
      nums = eratosthenes(1000000);
      free(nums);
   }
   timeit = clock() - timeit;
   t_total = (float)(timeit) / CLOCKS_PER_SEC;
   printf("time = %f\n", t_total);
}
--- End code ---

Andy Watson:
Going to unsigned long int is only going to get you one more bit of range. If you want to push the boat out a bit further you will have to go to long long ints.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod