Malloc works without type cast before malloc
我正在学习malloc函数,我阅读了以下内容:
其中n是要创建的整数。唯一的问题是PTR指向什么?编译器需要知道指针指向什么,这样才能正确地执行指针运算。换言之,如果编译器知道ptr是指向int的指针,则只能将ptr++或ptr=ptr+1解释为继续执行下一个int的指令。只要将ptr定义为指向要使用的变量类型的指针,这就有效。不幸的是,这引发了malloc如何知道指针变量的类型的问题——不幸的是,它不知道。
要解决此问题,可以使用类型转换。这个c对单词的播放是一种机制,用于强制值为特定类型。您所要做的就是在值前面的括号中编写类型说明符。所以:
1
| ptr = (*int) malloc(sizeof(int)*N ) |
但在malloc&;之前,我见过很多地方他们不使用(*int),甚至我也用它制作了一个链接列表,没有任何错误。为什么会这样?另外,为什么指针需要知道除了它们指向的内存大小以外的任何东西?不过,我又一次对这件事感到陌生,所以现在只有马尔洛克怀疑论能做到。
- 你读过吗?我是不是把malloc的结果投射出来的?
- 您完全、无可救药地混淆了语法和语义,并且误解了类型的必要性。除非您实际在指针上执行指针算术,否则编译器不需要知道它的确切类型。(更重要的是,由于void *需要隐式地从其他对象指针类型转换为其他对象指针类型。)此外,类型转换并不能解决问题。
- 请注意,如果您使用的是Visual Studio,那么如果您不强制执行malloc的返回,它将发出投诉。别理它。
- 你是用"使用VisualStudio"来编译"C代码+ C++编译器"吗?
- 指针不需要知道它们指向的内存大小:它们只需要知道它们是什么类型。编译器可以从声明中提取这个。CAST只是为了清晰:在C中并不需要,但是C++是必需的。顺便说一下,您的代码是错误的。它应该是(int*)而不是(*int)。
- 谢谢@grijeshchauhan不能说完全理解它,但掌握了它的窍门。需要学习更多。对不起,转贴了。
- @很好,那完全错了,对不起。MSVC也有一个C编译器——您应该使用它来编译C代码。千万不要用C++编译器编译C代码。是的,每一个C++编译器都会报告一个错误,因为C++有一个比C更严格的类型系统。
- @H2CO3正确。我不反对。VS支持C和C++。但是,即使您只编译C代码,编辑器也会抱怨某些C代码。这不是编译器的问题。这是一个IDE编辑器的问题。
- @伊尼切尔,呃,那太苛刻了。所以VS中的编辑器不在乎你是写C还是C++代码,它会把它当成C++来处理吗?(为Microsoft缓慢鼓掌…)
- @ H2CO3是的。不管您是否只编译为C。它将给出视觉提示,表明没有演员表的malloc是一个错误。它不一定把C++中所有无效的C代码当作错误来对待。malloc是一个让很多新的c-devs产生了malloc回归的元素。
- @是的,确实。(我很高兴也很自豪没有使用任何IDE。他们只是愚蠢的。)
在使用ptr之前,必须声明它,以及如何声明它是指针。malloc返回的void *被隐式转换为任何类型。
所以,如果你必须像
1 2
| int *ptr ;
ptr = malloc(sizeof(int)*N ); |
ptr将指向一个整数数组,如果声明为like
1 2
| char *ptr ;
ptr = malloc(sizeof(char)*N ); |
ptr将指向一个char数组,不需要强制转换。
建议不要从malloc中投射返回值。
But I have seen many places that they don't use (*int) before the
malloc & even I made a linked list with this and had no errors. Why is
that?
因为它们(当然还有您)以前将变量声明为一个指针,用于存储来自malloc的返回值。
why do pointers need to know anything except the size of memory they
are pointing to?
因为指针也用于指针算术,这取决于指针指向的类型。
- 如果您不想考虑类型,可以使用更好的C成语ptr = malloc(N * sizeof(*ptr));,它可以分配任意类型的n个项目,而不需要在分配时指定(仅在声明时指定)。
1 2 3 4
| malloc returns pointer of type void and void type pointer is implicitly
converted to any type so if you don 't use typecast then it will also work
int *ptr;
ptr=malloc(sizeof(int)*N) |
但是如果在C++中使用MALOC,则需要进行类型转换。
The only problem is what does ptr point at?
它指向一块大小为sizeof(int) * N的内存。
The compiler needs to know what the pointer points at so that it can do pointer arithmetic correctly.
您在代码中没有执行任何指针算术,因此这不适用。从malloc()返回void *很好,因为void *可以隐式转换为任何对象指针类型或从任何对象指针类型转换。
还要注意,将返回值强制转换为(int *)不会改变ptr本身的类型。所以没有任何好处。如果ptr是void *类型,那么即使编写了
1 2
| void *ptr ;
ptr = (int *)malloc(sizeof(int) * N ); |
我该如何更好地解释这一点?变量总是具有相同的类型,不管您为其分配的值是什么类型(例如,在这种情况下,将void *分配给int *是很好的,因为存在隐式转换。)
这就是为什么你不应该计算malloc()的回报值:它没有任何好处。它不能帮助正确性,它可以隐藏错误,降低可读性。
在为指针分配空间之前,需要声明指针
由于malloc的返回类型是void *,因此可以隐式转换为任何类型。因此
将为N整数分配空间。