0

Can someone please tell me what is wrong with this code?

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

char * prime(int N);

int main()
{

    char* p = prime(13);
    printf("%s", p);
    return 0;
}

char * prime(int N)
{
    int i,j=1;
    char yes[] = "Number is a prime";
    char no[] = "Number is not a prime";

    for(i=2; i<=N-1; i++)
    {
        if(N%i == 0)
            j=0;
    }

    if(j == 1)
        return yes ;
    else
        return no ;
}

Expected output =

Number is a prime

Shown output =

$0@

Vinay Prajapati
  • 7,199
  • 9
  • 45
  • 86
Akhil Raj
  • 457
  • 1
  • 4
  • 14
  • 3
    You must not return local pointer/array values in C. Those variables go out of scope when the function exits and the memory it points to is no longer valid. – kaylum Dec 17 '15 at 10:02
  • 2
    Replace `yes[]` with `*yes`, and `no[]` with `*no`, and your code will work fine. The other solution would be to get rid of the `yes` and `no` variables, and return the strings, e.g. `return "Number is a prime";` – user3386109 Dec 17 '15 at 10:14
  • @user3386109 How to return a string ? and how does the first method worked? How can we provide string to a pointer variable? – Akhil Raj Dec 17 '15 at 10:34
  • I know why we can provide string to a pointer variable , ignore that question . – Akhil Raj Dec 17 '15 at 10:43
  • 1
    Always compile your C code with (extra) warnings enabled. If you use GCC with the option `-Wall` the compiler should give you a warning about returning the address of a local variable. – August Karlstrom Dec 17 '15 at 11:12

1 Answers1

4

You're reading back data using a pointer which points to memory that you don't own; the behaviour on doing this is undefined.

yes and no are only defined in the function prime.

Once that function exits, the pointer is dangling.

Consider writing const char* yes = "Number is a prime"; etc. at global scope, change prime to return an int where 1 denotes primality and 0 doesn't, and use that return value in main to output the relevant string. Not only will this fix your bug but it's a nice design since prime should not really care how it's output value is consumed: that's the job of another function that's concerned with presenting the result. Your test for primality can also be optimised: in particular, you only need to go up to the square root of N.

Note how I've used const char* to indicate that the data are held in read-only memory.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • If we can give an address to a function as an argument , then why can't we return an address from a function ? Isn't both the process reverse of each other? – Akhil Raj Dec 17 '15 at 10:47
  • 1
    You can return an address from a function - you just can't sensibly return the address of a local variable which will cease to exist once your function returns. – Crowman Dec 17 '15 at 10:59