1

I'm relatively new to C (and completely new to StackOverflow - hey guys!), and this segfault has been giving me no surcease of sorrow for the past few hours (DevC++ on a windows machine). It's just a simple palindrome prime program, but it's really giving me a hard time. I'm not generally a novice programmer like it seems here, but... Good god. Now I remember why I wanted to get away from C++ and to Python so quickly.

#include <stdio.h>                                           
#include <stdlib.h>                                          
#include <errno.h>                                           
#include <string.h>                                         

FILE *outputFile;                                           
char buffer[81];
char* strrev();                                            
int bytesWritten;                                           
char* strI = 0;   


char *strrev(char str[])
{
   char *p1 =NULL;
   char *p2 =NULL;  

  if (! str || ! *str)
        return str;
  for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
  {
        *p1 ^= *p2;
        *p2 ^= *p1;
        *p1 ^= *p2;
  }
  return str;
}

main()                                                       
{ 
    int isPrime(int);

    int i,j;                                                                     
    outputFile = fopen("DD:OUTPUT", "w");                       
    if (outputFile == NULL)                                     
    {                                                           
       printf("open error:   %d/%s\n", errno, strerror(errno));   
       exit(99);                                                  
    }                                                                                                                          
for (i=1; i<15000; i++)                                  
{   

if (isPrime(i)==1)                                    
{                                                      
 bytesWritten = sprintf(buffer,"%d is primepal!\n",i);    
 fwrite(buffer, 1, bytesWritten, outputFile);          
}                                                      
}                                                                         
fclose(outputFile);                                       

return 0;                                                
}    

int isPrime(int myInt)                              
{                                                    

int loop;                                           

for (loop = 2; loop < myInt/2+1; loop++)
  sprintf(strI, "%s%d", 10, myInt);           
  {                                                   
      if (myInt%loop==0 && (atoi(strrev(strI))-myInt)==0)
      {                              
      return 0;                                       
  }                                                   
  return 1;                                         
  }
}                                                    

I apologize ahead of time if this is a dumb question, and the answer is very obvious -- but I've officially hit the limit where no matter how logical an answer, I've been coding the same problem for too long for it to make any sense. And also, segfaults are horrible beasts. Thank you ahead of time for anything you have to offer!

~ Jordan

j6m8
  • 2,261
  • 2
  • 26
  • 34
  • 2
    There's a Linux program called Valgrind that can tell you exactly where the segfault happened. There's a [question about Valgrind substitutes for Windows](http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows). – Brendan Long Oct 04 '11 at 20:42
  • Ahh, I was actually just on that question a few seconds ago -- definitely going to download that (and then pray that I never need to use it again). Thanks for the reference! – j6m8 Oct 04 '11 at 20:48
  • 1
    You probably will need to use it again, but it's not nearly so bad when you can just run `valgrind myprogram` and it prints out exactly what's wrong with your program. It even tells you line numbers for memory leaks in some cases. – Brendan Long Oct 04 '11 at 20:50
  • Your code does not check that the number is prime - merely that it is a palindrome. You should not return unconditionally from the body of the loop in `isPrime()`. – Jonathan Leffler Oct 04 '11 at 21:19
  • +1 for "no surcease of sorrow", and welcome to SO! – andronikus Oct 05 '11 at 18:59
  • Ah, thanks @JonathanLeffler! That helped. It's tough to get back into the swing of a language family once you leave it! And, glad you liked it, @andronikus! Thanks! – j6m8 Oct 11 '11 at 20:22

3 Answers3

5

The line sprintf(strI, "%s%d", 10, myInt); is likely crashing.

  • You have not allocated any space for strI, it's defined as char* strI = 0; Make it a char[64] , or a suitable size.
  • You're giving the wrong arguments to sprintf, "%s%d" says the first parameter should be a string ("%s") , but you give it an int. Change %s to %d

Some other issues:

  • Don't use *p1 ^= *p2; hack to to swap variables, there's many cases where this does not work. Do it properly with a temp variable.
  • main() calls isPrime(), but there's no prototype for isPrime at that time. Place int isPrime(int myInt); somewhere before main().
  • The prototype for your strrev function should be char *strrev(char str[]); and not char *strrev()
nos
  • 223,662
  • 58
  • 417
  • 506
  • Is there a way to hug people through the interwebsmachine? Thank you SOO SO SO SO much, I cannot express to you in words how much I appreciate your help! – j6m8 Oct 04 '11 at 20:48
  • Better yet, define `isPrime` before `main` and after `strrev`. – John Bode Oct 04 '11 at 20:51
  • 1
    @j6m8: there's much simpler way to thank on SO: accept the best answer and upvote all answers that you think are helpful – Andriy Tylychko Oct 04 '11 at 20:57
  • @ Everyone: Since I'm so new here, I promise I'll upvote you guys as soon as I have enough rep (15 required... gak) – j6m8 Oct 11 '11 at 20:24
3

Segfaults don't have to be as bad as you're experiencing. Compile the program with debugging symbols (add -g to gcc) and run it in gdb. After the segfault, type bt in gdb and press enter. It will tell you the exact line of your segfault.

dbeer
  • 6,963
  • 3
  • 31
  • 47
  • I'm using DevC++, so I wasn't getting any command-line interaction until you suggested this -- but I tried it, and voila! Line 63. Thanks! – j6m8 Oct 04 '11 at 20:50
0
for (loop = 2; loop < myInt/2+1; loop++)
  sprintf(strI, "%s%d", 10, myInt);           
  {
    if (myInt%loop==0 && (atoi(strrev(strI))-myInt)==0)

You might want to double-check where you've got that brace in relation to the for. This isn't python, and indentation alone doesn't cut it.

blahdiblah
  • 33,069
  • 21
  • 98
  • 152
  • Oh wow -- should have seen that coming! I even had to remove my colon from after the for line, and I've added countless forgotten semicolons. I feel like I'm a freshman in an intro to CS course. Thank you! – j6m8 Oct 04 '11 at 21:06