为什么以下代码不打印值10?

时间:2013-11-25 18:03:30

标签: c pointers

为什么以下代码不打印值10?相反,它崩溃..

void foobar(int *a) 
{   
    int *c;
    c = *a;

    printf("%d\n", *c);
}

int main(void)
{   
    int *b = (int *)malloc(sizeof(int));
    *b = 10;
    foobar(&b);
}   

6 个答案:

答案 0 :(得分:2)

尝试进行这些小改动。

#include <stdio.h>
#include <malloc.h>

void foobar(int *a) {
  printf("%d\n", *a); /* what was C about? */
}

int main(void) {
  int *b = malloc(sizeof(int));
  *b = 10;
  foobar(b); /* pass the pointer b, not the address of the pointer b. */
  free(b);
}

答案 1 :(得分:1)

首先,您应该加入stdio.hstdlib.h

其次,您的函数声明不正确。它应该是

void foobar(int **a)

而不是

void foobar(int *a)  

因为您正在将指针传递给指针。

答案 2 :(得分:0)

代码错过了包含<stdlib.h>,很可能在64位上运行。

要修复它:

#include <stdlib.h>  /* for prototype of malloc() */
#include <stdio.h>  /* for prototype of printf() */

void foobar(int ** a)  /* Fixed wrong type. */
{   
  int * c = *a;

  printf("%d\n", *c);
}

int main(void)
{    
  int * b = malloc(sizeof(*b)); /* Removed unnecessary and dangerous cast. */
  if (NULL != b) /* Added error checking. */
  {
    *b = 10;

    foobar(&b);
  }

  free(b); /* Added clean up. */

  return 0; /* Added return (unnecessary from C99 on). */
}  

答案 3 :(得分:0)

#include <stdio.h>
#include<stdlib.h> //--------> ERROR 3: INCLUDE STDLIB FOR MALLOC() FUNCTION

 void foobar(int *a)
{
    int *c;
    c = *a; //--------->ERROR 2 : C POINTS TO THE CONTENTS OF A POINTER

    printf("%d\n", *c);
}

 // SOLUTION 1 : KEEP FUNCTION PROTOTYPE SAME AND PASS B TO FOOBAR AND MAKE C POINT TO    A.
 // SOLUTION 2 : CHANGE FOOBAR'S PROTOTYPE TO FOOBAR(INT**A).

 int main(void)
{
     int *b = (int *)malloc(sizeof(int));
     *b = 10;
     foobar(b); //-------->ERROR 1 : PASSING THE ADDRESS OD A POINTER VARIABLE

}

溶液1:foobar(b);在main和c = a;

解决方案2:foobar(int ** a);

答案 4 :(得分:0)

由于void foobar(int * a)

中的错误参数类型而崩溃

它应该是无效的foobar(int ** a)

虽然要求正确的foobar(&amp; b)=&gt; foob​​ar的(b)中

答案 5 :(得分:0)

让我们谈谈一分钟的类型。

鉴于声明

T *p;

然后以下都是真的:

Expression         Type        Value
----------         ----        -----
         p         T *         Address of the thing p points to
        *p         T           Value of the thing p points to
        &p         T **        Address of the variable p

main中,您将b声明为int *。在foobar中,您将ac声明为int *类型。

在致电foobar时,您使用的是&b,其类型为int **;这与a的类型不匹配(并且应该导致编译器的诊断)。你正在做的是将变量 b的地址传递给foobar,这不是你想要的;您想传递b中包含的值,这是您从malloc调用中获取的内存的地址。因此,如果您将通话更改为foobar以阅读

foobar(b);

代码应该按预期工作。

图片可能会有所帮助。所有的地址都是凭空而来的,并不代表任何真实的平台;也假设大端代表:

Item        Address        0x00  0x01  0x02  0x03
----        -------        ----  ----  ----  ----
heap memory 0x00800000     0x00  0x00  0x00  0x0a
   b        0xfff78000     0x00  0x80  0x00  0x00
   a        0xfff781c0     0x00  0x80  0x00  0x00
   c        0xfff781c4     0x00  0x80  0x00  0x00

malloc的调用从地址0x008000000开始分配4个字节;在赋值*b = 10之后,这四个字节包含值0x0000000a。

bac都是auto范围的变量;这三个都包含堆内存地址作为它们的值。 表达式 *b*a*c都应评估为存储在地址0x008000000处的内容;也就是整数值10&b评估为b或0xfff78000的地址。

正如其他人所提到的,不要投射malloc的结果。它不是必需的(至少在1989年标准中没有C; C ++和早期版本的C是不同的故事),根据1989年的标准,如果忘记#include stdio.h,它可以抑制有用的诊断或者在范围内没有malloc的声明。 malloc来电的一般表格是

T *p = malloc( sizeof *p * num_elements );

所以在你的情况下它会读

int *b = malloc( sizeof *b );

请注意,您应该总是自己清理,即使对于这样的玩具程序,所以你要添加

free( b );
退出程序前