0

I'm new to programming and here's a program that can find out all the prime numbers within a limit. However, there is an error that says:

Prime 2(1682,0x7fff76316310) malloc: *** error for object 0x1002000a0: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug'

Also, Xcode reports an issue says 'signal SIGABRT'. I suspect that is has something to do with the function 'realloc'. What exactly is the problem and how to fix the code? Thanks!

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

const int unit=3;

unsigned long* expandMem(unsigned long *primePtr, unsigned long count){
unsigned long* newPtr=(unsigned long*)realloc(primePtr, (count+unit)*sizeof(unsigned    long));
return newPtr;
}


int main(){
unsigned long limit;
unsigned long count=0;
unsigned long* primePtr=(unsigned long*)malloc(sizeof(unsigned long)*unit);
*primePtr=2;

printf("Input the upper limit >>> ");
scanf("%ld",&limit);

for (unsigned long int number=3; number<=limit; number+=2) {
    bool isPrime=true;
    for (unsigned long i=0; (*(primePtr+i))*(*(primePtr+i))<=number; i++) {
        if (number%(*(primePtr+i))==0) {
            isPrime=false;
            break;
        }
    }
    if (isPrime) {
        count++;
        *(primePtr+count)=number;
        if (count%unit==2) {
            primePtr=expandMem(primePtr, count);
        }
    }
}
for (unsigned long i=0; i<=count; i++) {
    printf("%ld ",*(primePtr+i));
}
}
  • 2
    [Please don't cast the return value of `malloc()` and friends, in C](http://stackoverflow.com/a/605858/28169). Also, for readability, you should *really* replace all cases of `*(p + i)` with `p[i]`. – unwind Jan 10 '14 at 11:15
  • @unwind Should a cast the return value of realloc()? –  Jan 10 '14 at 11:21
  • 1
    To begin with, replace all occurrence of `*(primePtr+x)` with `primePtr[x]`. This is just in order to improve the code readability. – barak manos Jan 10 '14 at 11:21
  • @user3181273 No, that's what I meant by "and friends". You should never cast a (data) pointer from `void *` to some other type, in C. – unwind Jan 10 '14 at 11:25

1 Answers1

0

The realloc will only allocate space for 2 new elements but you assume it allocates space for 3 new elements.

Suggested change (in expandMem):

unsigned long* newPtr=(unsigned long*)realloc(primePtr, (count+1+unit)*sizeof(unsigned    long));
Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
  • Thanks! The modification works well. But what does 'The realloc will only allocate space for 2 new elements' mean? –  Jan 10 '14 at 11:38
  • Do you mean that you can only fill in an even number in that bracket? –  Jan 10 '14 at 11:40
  • No, I mean that count is the highest index, which is one less than the number of elements since array indexes start at 0. That's why you need to add `1`. A better way to fix the problem would actually be to add one in the call instead: `primePtr=expandMem(primePtr, count + 1);` because that would give better semantics to the expandMem function. – Klas Lindbäck Jan 10 '14 at 12:28
  • Now I understand. The program now works perfectly. You are greatly appreciated. –  Jan 10 '14 at 13:32