代码使我感到困惑。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void create_int(int *p)
{
p = (int *) malloc(sizeof(int));
}
int main()
{
int *p = NULL;
create_int(p);
assert(p != NULL); /* failed. why? I've allocated memory for it. */
return 0;
}
答案 0 :(得分:7)
您没有从函数返回指针值。尝试:
void create_int(int **p) {
*p = (int *) malloc(sizeof(int));
}
int main() {
int *p = NULL;
create_int(&p);
assert(p != NULL); /* failed. why? I've allocated memory for it. */
return 0;
}
答案 1 :(得分:2)
你需要一个指针指向这样的指针:
void create_int(int **p)
{
*p = (int *) malloc(sizeof(int));
}
int main()
{
int *p = NULL;
create_int(&p);
assert(p != NULL); /* failed. why? I've allocated memory for it. */
return 0;
}
答案 2 :(得分:2)
函数p
中的变量create_int
是p
中变量main
的副本。因此,对p
中的main
所做的任何更改都不会反映在main
中。
要使更改反映在int* create_int(int *p) {
p = malloc(sizeof(int));
// err checking
return p:
}
...
// in main:
p = create_int(p);
中,您需要:
返回更改后的值:
p
或将void create_int(int **p) {
*p = malloc(sizeof(int));
// err checking
}
...
// in main:
create_int(&p);
的地址传递为:
{{1}}
答案 3 :(得分:2)
正如大家所指出的那样,它失败了,因为你实际上并没有改变调用者的指针。
考虑代码的另一种方式可能是注意它基本上包裹malloc()
,即它正在进行内存分配但是增加了智能。在这种情况下,为什么不让它与malloc()
具有相同的原型(=呼叫签名)?这使得调用者的上下文更加清晰,更容易使用:
int * create_int(void)
{
return malloc(sizeof (int));
}
int main(void)
{
int *p = create_int();
assert(p != NULL);
return 0;
}
另外,在C中你绝不应该转换malloc()
的返回值(见Do I cast the result of malloc?)。
答案 4 :(得分:1)
您需要发送指向指针的指针,以便能够通过函数
为其分配内存void create_int(int **p)
{
*p = (int*)malloc(sizeof_int));
}
int main()
{
int* p = NULL;
create_int(&p);
assert(p != NULL);
return 0;
}
答案 5 :(得分:0)
您的代码包含两个指针:create_int
函数中的一个和main
中的另一个。当您致电create_int
时,main
中的指针的副本会被生成并使用,当create_int
函数返回时,消除 。
因此,您对create_int
中的副本所做的任何更改仍然存在,并且不会传播回main
。
在C中的函数之间传播更改的唯一方法(除了显然返回新值)是传递指向已更改值的指针。这样,虽然传递的指针将被复制,但它指向的值将是相同的,因此将适用更改。
由于您正在尝试更改指针,因此需要一个指向指针的指针。
void create_int(int **pp)
{
// this changes the pointer that `p` points to.
*pp = (int *) malloc(sizeof(int));
}
int main()
{
int *p = NULL;
// this sends a pointer to the pointer p in main
create_int(&p);
assert(p != NULL);
return 0;
}