C语言中的以下代码有什么问题?

时间:2017-03-15 08:20:04

标签: c pointers

我在行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();
}
  • (A)编译错误,因为malloc的返回不是类型转换 适当。
  • (B)编译器错误,因为比较应该是x == NULL 而不是如图所示。
  • (C)编译成功,但执行可能会导致悬空 指针。
  • (D)编译成功但执行可能导致内存泄漏。
  

在我看来,选项D 仅在使用int *x = (int *)malloc(sizeof(int));时才正确。

4 个答案:

答案 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));

分配的内存中的第一个mallocx。第二个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编译它而不进行类型转换,则不会出现编译错误。