我在行int *x = malloc(sizeof(int));
中观察到这个代码试图将void *转换为int *而不使用正确的类型转换。所以根据我的回答应该是选项A 。但是在官方的GATE-2017考试答案中,答案是D。我错了吗?怎么样?
#include<stdio.h>
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
int *assignval(int *x, int val){
*x = val;
return x;
}
void main(){
clrscr();
int *x = malloc(sizeof(int));
if(NULL==x) return;
x = assignval(x,0);
if(x){
x = (int *)malloc(sizeof(int));
if(NULL==x) return;
x = assignval(x,10);
}
printf("%d\n",*x);
free(x);
getch();
}
在我看来,选项D 仅在使用
int *x = (int *)malloc(sizeof(int));
时才正确。
答案 0 :(得分:6)
所提供的选择中没有正确答案。
代码的明显问题,假设代码应该用标准C编写:
标准库没有<conio.h>
标题或<iostream.h>
标题。
void main()
是非法的。应该是int main()
。更好int main(void)
clrscr()
,getch()
- 标准库不知道此类功能。
第二个malloc
泄漏第一个分配的内存(假设第一个成功)。
第二个malloc
的结果是明确施展的 - 糟糕且不必要的做法。
答案 1 :(得分:0)
声明:
int *x = malloc(sizeof(int));
不会导致编译错误,因为它将x
声明为int
的指针并在之后对其进行初始化。它事先没有void
类型。
声明:
x = (int *)malloc(sizeof(int));
导致可能的内存泄漏,因为它重新分配已为x
分配的内存。
注意: 但是这些答案都不完全正确。由于各种原因,此代码无法编译。
如果这是您的代码,请更改:
void main()
到:
int main(void)
并且还可以看到why you should not cast the result of malloc。
除此之外,标准库无法识别clrscr()
,getch()
,<conio.h>
和<iostream.h>
。
答案 2 :(得分:-1)
我在行中观察到int * x = malloc(sizeof(int));此代码尝试将void *转换为int *而不使用正确的类型转换。
There's more than a little debate about whether or not to cast malloc
,但这是一种风格。 void *
被安全地提升为任何其他指针。
ISO C 6.3.2.3说......
指向void的指针可以转换为指向任何不完整或对象类型的指针。指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回;结果应该等于原始指针。
无论你选择什么,选择一个并坚持下去。
内存泄漏在这里:
int *x = malloc(sizeof(int));
if(NULL==x) return;
x = assignval(x,0);
if(x){
// Memory leak
x = (int *)malloc(sizeof(int));
分配的内存中的第一个malloc
点x
。第二个malloc
只有在第一个成功时才会发生(如果x
为真)。指向第一个malloc
分配的内存的指针将丢失。
使用新变量可以修复泄漏,请记住代码是无意义的。
int *x = malloc(sizeof(int));
if(NULL==x) return;
x = assignval(x,0);
if(x){
int *y = malloc(sizeof(int));
if(NULL==y) return;
y = assignval(y,10);
free(y);
}
作为旁注,void main()
技术上 不违反ISO C标准,它是“其他一些实现定义的方式”。< / p>
5.1.2.2.1说:
程序启动时调用的函数名为main。该实现声明此函数没有原型。它应该用返回类型int定义,没有参数:
int main(void){/ * ... * /}
或者有两个参数(这里称为argc和argv,虽然可以使用任何名称,因为它们是声明它们的函数的本地名称):
int main(int argc,char argv []){/ ... * /}
或等效的;) 或其他一些实现定义的方式 。
我猜你正在使用Windows编译器,这将是“其他一些实现”。 clang
认为这是一个错误。
test.c:8:1: error: 'main' must return 'int'
void main(){
^~~~
int
1 error generated.
答案 3 :(得分:-1)
你永远不要忘记可以为所有类型的指针分配一个void *指针。在像visual studio这样的IDE中,如果在向&lt;&gt;指定void *时不执行转换,则会出现编译错误。例如:
float *ptr = malloc(sizeof(float));//compile error in visual studio.
但是如果你使用GCC编译它而不进行类型转换,则不会出现编译错误。