一个奇怪的内存赋值, while导致的惨剧

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012266559/article/details/84137804

先上代码

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

int main()
{
    char str_t[]="This String comes from t";//初始化字符数组
    char str_s[]="This is an empty s";//初始化字符数组
    printf("%s %u\n%s %u\n",str_t, strlen(str_t), str_s, strlen(str_s));
    printf("str_t %p %p\nstr_s %p %p\n", str_t, &str_t[strlen(str_t)-1], str_s, &str_s[strlen(str_s)-1]);

    char *t=str_t;//初始化字符指针
    char *s=str_s;//初始化字符指针
    while(*s++=*t++);//*的优先级比++高,且为右结合,因此会将t的值逐个赋值给s,直到结果为'\0'
    printf("\n%s %u\n%s %u\n",str_t, strlen(str_t), str_s, strlen(str_s));
    printf("str_t %p %p\nstr_s %p %p\n", str_t, &str_t[strlen(str_t)-1], str_s, &str_s[strlen(str_s)-1]);
    return 0;
}
root@ubuntu:# ./xx
This String comes from t 24
This is an empty s 18
str_t 0xbfc488d3 0xbfc488ea
str_s 0xbfc488c0 0xbfc488d1

rom t 5
This String comes from t 24
str_t 0xbfc488d3 0xbfc488d7
str_s 0xbfc488c0 0xbfc488d7
root@ubuntu:# 

分析

  1. 第一次的输出可以看出,str_t 从0xbfc488d3 开始;str_s从0xbfc488d1结束。中间只有一个‘\0’的分割。从起始地址上也可以看出,栈是向下生长的,但是栈空间是向上扩展的。
  2. 从第二次输出可以看到,str_s的末尾向后移动了6个字节,毕竟这是栈内存,不需要申请。结果就是str_s侵占了str_t的栈空间,直接导致了0xbfc488d8变成‘\0’,从而使strlen(str_t)时计算错误。

结论

直接导致这一惨剧的是 while(*s++=*t++) 所以最好摒弃掉这种书写方式。

猜你喜欢

转载自blog.csdn.net/u012266559/article/details/84137804