s4.ax1x.com/2022/01/04/TOB5oq.png
为啥么会这样报错呢,看不懂了(不会发图,希望大佬教一下)

嗡嗡嗡,求回复

不懂

memset 时,把变量 c 强制转成 unsigned char*。c 是 int 型指针,你如果对 8 个单位清零,应该是越界了^_^

一眼没看出问题,但是 memset 是不是应该在 if 里面才对?(虽然这不是引发问题的原因。)

破案了,我觉得应该不是越界了
没有强转啊

#include <stdlib.h>

加了这个好了,但是我仍然不知道为什么

static int *c = NULL;

笔试的时候别说是我教的.

代码没啥问题。。。所以,应该是别的问题

malloc 函数在 stdlib.h 里面,memset 函数在 string.h 里面,printf 在 stdio.h 里面,正常来说你需要把这三个头文件都加上。我刚刚还特地试了下,gcc 9.3.0 下可以正常编译和运行,没有任何问题,但是不加头文件的话会弹警告(实际上就是默认给加上了)。

按理说没有 stdlib.h 用不了 malloc

试试没有 include 的情况下,能不能从 IDE 跳过去。。。。

When the application is linked with a debug version of the C run-time libraries, malloc resolves to _malloc_dbg

docs.microsoft.com/en-us/cpp/c-runtime-library/reference/malloc?view=msvc-170

盲猜没引入 stdlib.h 所以没解析到 _malloc_dbg ,隐式连接了正统 malloc ,然后调试器跪了

正解正解
话题终结

好丢人啊,这么低级的错误
(确实好久没用这个函数了,公司不让用,有其他的函数申请内存)

因为如果你不引入 malloc 的声明的话,按照 k&r c 的遗留标准,这个函数会被声明为 int (*)(), 于是在 64 位平台上 malloc 的返回值,那个指针,有可能被截断为一个 int ,导致你 c 指向的地方不对了。这也就是为什么 modern c 里推荐不要强转 malloc 返回值,以检测到这类错误

不大确定,希望多加指正

当然我觉得理论上现代编译器应该能检测到这种问题,尤其是对这么常见的函数,所以我觉得 老哥的解释也很有可能,这可能需要看看编译出的汇编是怎么样的才能决定了(当然两个原因有可能一起发生也说不定)

最新的 MSVC 其实有弹警告,你可能没注意到。

warning C4013: “malloc”未定义;假设外部返回 int

根据提示我猜测:
编译器没找到 malloc 的定义,然后默认返回的 int* 为 int 。
然后链接器是正常 link 到了 malloc 上,在 32 位下面这样是没问题的,但如果编译 64 位的程序返回的 int 本来是占 8 字节但是编译器强行截断成了 4 字节的 int 在赋值给 int 所以地址就不对了。

我自己实测结果:VS2022
编译位 X86 不加 stdlib.h 运行调试都没问题
如果编译为 X64 不加的情况下调试就会弹错误了。

#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!

这里为啥会这样呢??? 虽然我知道和变量生命周期有关,但是为什么会留一半呢???

厉害啊,老哥,原来还有这样一说

是 ub ,第一个程序理论上可以出现任何行为,包括让你电脑爆炸

未定义行为的结果就不要纠结了。

莫非是嵌入式的?不让用标准库

看代码的时候确实看到 include 段太短,猜到了没引入头文件,但没猜到默认返回类型太短截断指针的问题。