
#include <iostream> using namespace std; struct A{ const char* a; }; void f(A* a){ string s("abc"); a->a = s.c_str(); } nt main(int argc, char* argv[]){ A a; f(&a); printf("a: %s\n", a.a); return 0; } 这属于 ub 的问题吗?
1 zwzmzd 2018-09-19 09:27:26 +08:00 via iPhone s 都随着函数 f 结束销毁了,再去用 c_str 本身就有问题 |
3 ai277014717 2018-09-19 09:42:33 +08:00 编译器内部实现不一样造成的吧 |
4 seancheer 2018-09-19 09:46:13 +08:00 @zynlp 内存释放并不代表那块内存里面的内容会被写成 0,只是说这块内存可以被其他代码使用了。。你这个时候访问一块已经释放的内存虽然这会儿正常,但是不保证过一段时间还是正常的。。当程序规模比较大的时候,这块内存很有可能很快就被其他代码段使用了。 这就是传说中踩内存中的一种情况。 |
5 liangweijia6000 2018-09-19 09:49:13 +08:00 这是想研究啥。。 |
6 zivyou 2018-09-19 09:49:45 +08:00 会不会不同平台的垃圾清理方式不同导致的?比如 windows 中,在函数调用完之后,该函数的局部变量就被清理;而 Linux 将这个动作延迟到了进程退出(只是一种推测,我没有证实过)。 |
7 dynamicheart 2018-09-19 09:50:16 +08:00 via iPhone @zynlp 在 Linux 下,离开 f 作用域后,s 被销毁了,a 指向的是一个无效的地址空间,但因为这段内存空间还没有被复用,里面的数据还是 abc,所以打印出来的是 abc。 |
9 disk 2018-09-19 09:51:51 +08:00 via Android 别这样,vs 安全检查比较严格,你不知道什么时候悬空 |
10 wdlth 2018-09-19 09:55:07 +08:00 我在 Linux 下执行是返回乱码 |
11 ipwx 2018-09-19 10:02:55 +08:00 这是未定义行为吧,你去理解它没有意义。 |
12 Rosanta 2018-09-19 10:13:37 +08:00 UB 有啥好研究的,你开不一样的优化等级输出还不一样呢 |
13 rocbomb 2018-09-19 10:13:54 +08:00 想起了大一 C 语言课本上的 a=(i++)*(i++)*(i++)*(i++)*(i++)*(i++); 这种代码在工作中 谁写出来我非打死他不可 |
14 seancheer 2018-09-19 10:14:27 +08:00 @zynlp 不一定啊。。和具体实现相关。具体就要找下 vc 和 linux 下的实现区别了。不过个人觉得死磕这个没有意义。 你代码本身就是错误的行为,真正系统下是肯定会出问题的,无论 vc 还是 g++ |
15 sbw 2018-09-19 11:36:03 +08:00 学习一下 Rust 你就知道 |
18 429839446 2018-09-19 14:19:08 +08:00 请看 cppreference, c_str()这样用是未定义行为. |
19 shilyx 2018-09-19 14:20:32 +08:00 一楼说得对,代码错了,这是前提。 错了的代码输出什么,只能回答:是什么就是什么,无任何保证。 你汇编跟踪以下,也能搞清楚为什么会那样输出,一句话,各有各的道理,编译器不背锅。 |
20 nutting 2018-09-19 14:29:24 +08:00 g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16),编译不过去 Apple LLVM version 7.3.0 (clang-703.0.29),编译后运行,输出乱码 |
21 tourist2018 2018-09-19 15:15:34 +08:00 @zivyou #6 和操作系统应该没关系 和编译器有关系 而且可以直接使用 printf 方法么?这不是 stdio.h 里面的库函数? |
22 wwqgtxx 2018-09-19 17:49:44 +08:00 @tourist2018 有些编译器的 iostream 文件中会导入 cstdio 所以可以直接用 |
23 neptuno 2018-09-19 17:59:24 +08:00 编译器不一样。有些未定义行为在不同编译器不一样的 |
24 iceheart 2018-09-19 23:17:02 +08:00 via Android 这不是 ub,这是野指针 |
25 msg7086 2018-09-20 00:34:50 +08:00 刚想说,这就是野指针啊。(然后楼上说了。) 随便指向内存中一块不属于你的地址,出来的是啥就是啥。 如果内核看你不爽,可以直接杀掉你的进程。如果他没那么凶,那就让你随便读点内存里的辣鸡数据。 |