-
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)
#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);
}
The program works fine with eratosthenes(10000) and raise memory error with eratosthenes(100000)
-
Good practice to check to see if a malloc succeeded. That'll eliminate the run-time error.
nums = malloc(n+1);
if (!nums){ // malloc failed
return NULL;
}
It would appear that 32K (2**15) is likely the limit for malloc() in your environment or using those compilers.
-
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.
-
Thanks, that is the problem.
running program:
#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);
}
-
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.
-
Thanks, but that would slow down the program.
The problem is solved with this sentence:
x = i*i;
if (x > n)
break;
-
.
-
I was using Borland C for 32 bits. Only have one memory model for 32 bits.
Now, with corrections, the program compile and run correctly with Borland C, TinyC Compiler and GCC.
-
Yes, of course, there were Borland C and C++ compilers for Windows, and Windows 32 bits, with just a flat memory model.
16-bit code on x86 required a segmented memory model. A real pain. And so compilers usually supported several "memory models" depending on your projected use of memory, with various tradeoffs.
-
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.
Are you running on something older than a 386?
-
I thought the same the first time, that it was a memory segmentation problem.
But no, it was a problem with the square of a long number.
It is already solved. Thanks.
-
ah sweet memories ... Borland Turbo C on an Olivetti Quaderno 33 (PT-AT-60) that my uncle bought abroad and gave me on his return.
I was so excited because it was my first laptop, today it doesn't sound too great ... Intel 80386, 20MHz, 4MB of RAM (later expanded to 12MB by a PCMCIA RAM card), 60MB Hard disk, and MS-DOS v5.0
I remember never using "malloc()" with Turbo C because it was too problematic. I remember using just a static ram construct, kind of "make your malloc on the heap" or something.
~ 25 years ago, I don't remember details :-//