Why is strcpy(strerror(errno),"Hello") not copying "Hello",but {ptr=strerror(errno);strcpy(ptr,"Hello");} does?

StackOverflow https://stackoverflow.com/questions/16546825

Question

Please explain what's going on in the following program.

I checked out the addresses returned by strerror(errno) at the beginning and end of the program and it confirms that it returns the same address each time.Then once sure of this,in first case I proceeded to assign that same address to ptr and then copy a string "Hello" to it using strcpy().In case II,I tried to copy "Hello" directly to the address returned by strerror(errno).I had odd findings.I'll appreciate if you explain the following:

In case one,I copied "Hello" to ptr and it is successful as in the subsequent printf(),ptr prints Hello.But then, when I passed strerror(errno) instead of ptr to printf(),it prints the old error message.How is it possible that ptr points to one message but strerror(errno) points to another message when both addresses are same?I verified both addresses are same and I expect that copying "Hello" to ptr should be same as copying it to the return of strerror(errno).To doubly check this discrepancy,then I tried to copy "Hello" directly to strerror(errno) but it doesn't work this time too and it prints the same old error string.But the surprising thing is,at this point too, I verified again that the addresses ptr and strerror(errno) are indeed same all along!! How is it possible?If they are same how are they pointing to different strings?One to "Hello" and other to the old custom error message?

Please explain the reason behind this.

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

int main ()
{ char *ptr;
  FILE * fp;
  fp = fopen ("missingfile.txt","r");
  if (fp == NULL)
    printf ("%s\n",strerror(errno));
    printf("\n%p",strerror(errno));  //Initial address

    //Case1:
    ptr=strerror(errno);
    strcpy(ptr,"Hello");
    printf("\n%s",ptr);  //Prints Hello
    printf("\n%s",strerror(errno)); //Still prints old message


    //Case2:
    strcpy(strerror(errno),"Hello"); //Doesn't copy Hello there
    printf("\n%s",strerror(errno)); //Still prints old message


    printf("\n%p",strerror(errno)); //Address same as it was at start
    printf("\n%p",ptr);  //same address as above statement


  return 0;
}

OUTPUT

No such file or directory

00032508
Hello
No such file or directory
No such file or directory
00032508
00032508
Was it helpful?

Solution

In

//Case2:
strcpy(strerror(errno),"Hello"); //Doesn't copy Hello there
printf("\n%s",strerror(errno));

Your second call to strerror in the printf overwrites what you copied.

This is bad-form, all the way around.

OTHER TIPS

From the manual page:

This string must not be modified by the application, but may be modified by a subsequent call to strerror().

So while the function doesn't return a const pointer, it should nevertheless not be modified, and that includes copying to it.

The strerror may in fact have a static buffer, which is the reason you get the same pointer returned from it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top