1
zhangjinghua OP 嗡嗡嗡,求回复
|
2
dlsflh 2022-01-04 21:26:09 +08:00 via Android
不懂
|
3
TaylorJack123 2022-01-04 21:42:21 +08:00 via iPhone
memset 时,把变量 c 强制转成 unsigned char*。c 是 int 型指针,你如果对 8 个单位清零,应该是越界了^_^
|
4
msg7086 2022-01-04 21:51:46 +08:00 via Android
一眼没看出问题,但是 memset 是不是应该在 if 里面才对?(虽然这不是引发问题的原因。)
|
5
zhangjinghua OP 破案了,我觉得应该不是越界了
没有强转啊 #include <stdlib.h> 加了这个好了,但是我仍然不知道为什么 |
6
basncy 2022-01-04 21:55:16 +08:00
static int *c = NULL;
笔试的时候别说是我教的. |
7
iOCZ 2022-01-04 21:59:45 +08:00
代码没啥问题。。。所以,应该是别的问题
|
8
xiri 2022-01-04 21:59:59 +08:00
@zhangjinghua
malloc 函数在 stdlib.h 里面,memset 函数在 string.h 里面,printf 在 stdio.h 里面,正常来说你需要把这三个头文件都加上。我刚刚还特地试了下,gcc 9.3.0 下可以正常编译和运行,没有任何问题,但是不加头文件的话会弹警告(实际上就是默认给加上了)。 |
9
Tanix2 2022-01-04 22:01:51 +08:00
@zhangjinghua 按理说没有 stdlib.h 用不了 malloc
|
10
iOCZ 2022-01-04 22:04:17 +08:00
试试没有 include 的情况下,能不能从 IDE 跳过去。。。。
|
11
ipwx 2022-01-04 22:05:51 +08:00
When the application is linked with a debug version of the C run-time libraries, malloc resolves to _malloc_dbg
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/malloc?view=msvc-170 盲猜没引入 stdlib.h 所以没解析到 _malloc_dbg ,隐式连接了正统 malloc ,然后调试器跪了 |
12
zhangjinghua OP @xiri 正解正解
话题终结 |
13
zhangjinghua OP 好丢人啊,这么低级的错误
(确实好久没用这个函数了,公司不让用,有其他的函数申请内存) |
14
Origami404 2022-01-04 22:12:45 +08:00 via Android 2
@zhangjinghua 因为如果你不引入 malloc 的声明的话,按照 k&r c 的遗留标准,这个函数会被声明为 int (*)(), 于是在 64 位平台上 malloc 的返回值,那个指针,有可能被截断为一个 int ,导致你 c 指向的地方不对了。这也就是为什么 modern c 里推荐不要强转 malloc 返回值,以检测到这类错误
不大确定,希望多加指正 |
15
Origami404 2022-01-04 22:15:52 +08:00 via Android
当然我觉得理论上现代编译器应该能检测到这种问题,尤其是对这么常见的函数,所以我觉得 @ipwx 老哥的解释也很有可能,这可能需要看看编译出的汇编是怎么样的才能决定了(当然两个原因有可能一起发生也说不定)
|
16
wevsty 2022-01-04 22:16:52 +08:00
最新的 MSVC 其实有弹警告,你可能没注意到。
warning C4013: “malloc”未定义;假设外部返回 int 根据提示我猜测: 编译器没找到 malloc 的定义,然后默认返回的 int* 为 int 。 然后链接器是正常 link 到了 malloc 上,在 32 位下面这样是没问题的,但如果编译 64 位的程序返回的 int* 本来是占 8 字节但是编译器强行截断成了 4 字节的 int 在赋值给 int* 所以地址就不对了。 |
17
wevsty 2022-01-04 22:18:48 +08:00
我自己实测结果:VS2022
编译位 X86 不加 stdlib.h 运行调试都没问题 如果编译为 X64 不加的情况下调试就会弹错误了。 |
18
zhangjinghua OP #include <stdio.h>
#include <stdlib.h> int* a = NULL; int* b() { int c[2] = { 0 }; if (c != NULL) { c[0] = 123; c[1] = 456; } return c; } int main() { a = b(); printf("a[0] : %d \n", a[0]); printf("a[1] : %d \n", a[1]); printf("Hello World!\n"); } 结果 : a[0] : 123 a[1] : 0 Hello World! #include <stdio.h> #include <stdlib.h> int* a = NULL; int* b() { static int c[2] = { 0 }; /////////这里加了 static if (c != NULL) { c[0] = 123; c[1] = 456; } return c; } int main() { a = b(); printf("a[0] : %d \n", a[0]); printf("a[1] : %d \n", a[1]); printf("Hello World!\n"); } 结果 a[0] : 123 a[1] : 456 Hello World! 这里为啥会这样呢??? 虽然我知道和变量生命周期有关,但是为什么会留一半呢??? |
19
zhangjinghua OP @wevsty 厉害啊,老哥,原来还有这样一说
|
20
Origami404 2022-01-04 22:23:46 +08:00 via Android
@zhangjinghua 是 ub ,第一个程序理论上可以出现任何行为,包括让你电脑爆炸
|
21
wevsty 2022-01-04 22:24:15 +08:00
@zhangjinghua
未定义行为的结果就不要纠结了。 |
22
iOCZ 2022-01-04 22:39:44 +08:00
莫非是嵌入式的?不让用标准库
|
23
msg7086 2022-01-04 23:08:41 +08:00 via Android
看代码的时候确实看到 include 段太短,猜到了没引入头文件,但没猜到默认返回类型太短截断指针的问题。
|