请解释以下程序中发生了什么。
我检查了strerror(errno)
在程序开头和结尾返回的地址,并确认每次都返回相同的地址。然后一旦确定,在第一种情况下,我继续分配相同的地址。地址为ptr
,然后使用"Hello"
将字符串strcpy()
复制到其中。在案例II中,我尝试将"Hello"
直接复制到strerror(errno)
返回的地址我有奇怪的发现。如果您解释以下内容,我将不胜感激:
如果是第一种情况,我会将"Hello"
复制到ptr
,并且会在后续printf()
,ptr
打印Hello
时成功。但是,当我将strerror(errno)
而不是ptr
传递给printf()
,它会打印旧的错误消息。ptr
如何指向一条消息但strerror(errno)
指向两个地址相同时的另一条消息?我确认两个地址都相同,我希望将"Hello"
复制到ptr
应该与将其复制到strerror(errno)
的返回值相同。要加倍检查这个差异,然后我尝试将"Hello"
直接复制到strerror(errno)
,但这次也不起作用,并打印出相同的旧错误字符串。但令人惊讶的是,此时我也验证了地址ptr
和strerror(errno)
一直都是一样的!它是如何可能的?如果它们是相同的,它们如何指向不同的字符串?一个到"Hello"
和其他旧的自定义错误消息?
请解释背后的原因。
#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;
}
输出
No such file or directory
00032508
Hello
No such file or directory
No such file or directory
00032508
00032508
答案 0 :(得分:6)
在
//Case2:
strcpy(strerror(errno),"Hello"); //Doesn't copy Hello there
printf("\n%s",strerror(errno));
您对strerror
中printf
的第二次电话会覆盖您复制的内容。
这是一种糟糕的形式,一直到处都是。
答案 1 :(得分:3)
该字符串不得由应用程序修改,但可以通过后续调用 strerror()进行修改。
因此,虽然该函数没有返回const
指针,但它应该不进行修改,并且包括复制到它。
strerror
实际上可能有一个static
缓冲区,这就是你从它返回相同指针的原因。