0xE*_*D1E 10 c printf pointers
我最近写了一个简单的程序来反转一个字符串,我的程序只是接受来自用户的输入字符串然后反转它.这一切都是用2个指针完成的.关于程序中的指针安全性,我编写了一个复制给定字符串的函数,该函数为新的(相同长度)字符串分配内存,然后逐个复制字符.
我的问题是当我运行这个程序时,虽然它做了我需要的东西,它打印出一些神秘的额外输出.在接受用户的输入之前,它每次都这样做.这是我运行程序时发生的情况.
C:\Users\0xEDD1E\Desktop\revstr>revstr.exe
[C]
[.]
[revstr.exe]
hello
[hello]
olleh
Run Code Online (Sandbox Code Playgroud)
这里最后三行是输入和输出,没关系,问题出在前3行
[C]
[.]
[revstr]
Run Code Online (Sandbox Code Playgroud)
那些是什么?无论如何,这是我的计划
#include <stdio.h>
#include <stdlib.h>
#define swap(a, b) (((a) ^ (b)) && ((a) ^= (b), (b) ^= (a), (a) ^= (b)))
unsigned long strlen_(char *);
char *strdup(char *s);
char *reverseString(char *, int);
int main(void)
{
//fflush(stdout);
char *str = (char *) malloc(1024 * sizeof (char));
scanf("%[^\n]s", str);
int slen = strlen_(str);
printf("%s\n", reverseString(str, slen));
return 0;
}
unsigned long strlen_(char *s)
{
char *p = s;
while (*p) p++;
return p - s;
}
char *strdup(char *s)
{
char *p = (char *) malloc((size_t) (strlen_(s) + 1) * sizeof (char));
if (p) {
char *pp = p;
while ((*pp++ = *s++)) ;
}
printf("[%s]\n", p);
return p;
}
char* reverseString(char* s, int n)
{
char *str = strdup(s);
char *p = str - 1;
char *q = str + n;
while (++p < --q) {
swap(*p, *q);
}
return str;
}
Run Code Online (Sandbox Code Playgroud)
你可以看到,在看,strdup()功能,通过产生的那些线printf()的strdup()(因为功能printf("[%s]\n, str);).
所以我想我找到了错误点.但我无法弄清楚这个错误的原因,以及解决它的方法.特别是这只发生在Windows上(我的是Windows 10 Pro).我在Ubuntu(64位)上测试了这个,在Ubuntu中没有这样的bug.
我的直觉告诉我这个错误必须用函数中使用的指针做一些事情
更新:我试过,fflush(stdout)但没有帮助
这个Bug(或行为不端)背后的原因是什么,有人可以解释原因吗?
M.M*_*M.M 16
可能,您的系统的C库也定义了一个函数strdup,程序启动中的一些代码调用该函数.然后链接器将这些调用链接到您的strdup函数而不是系统函数.
为避免这种情况,请不要命名您的函数strdup或str任何名称:保留名称开头str和小写字母(C11 7.31.12,7.31.13); 在自己的代码中使用它们作为函数名称会导致未定义的行为.
NB.char *p = str - 1;通过在任何对象的边界之外进行指针运算,也会导致未定义的行为.(例如,想象一下,str恰好是地址空间中的第一个地址).将算法重组为不指出界限是很好的.