为什么以下代码不打印值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);
}
答案 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.h
和stdlib.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
解决方案2:foobar(int ** a);
答案 4 :(得分:0)
由于void foobar(int * a)
中的错误参数类型而崩溃它应该是无效的foobar(int ** a)
虽然要求正确的foobar(&amp; b)=&gt; foobar的(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
中,您将a
和c
声明为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。
b
,a
和c
都是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 );
退出程序前。