在一个函数中分配内存并在另一个函数中使用它
Allocate memory in one function and use it in another function
以下代码似乎有效。 linux 上的 gcc 5.2.1 没有给出任何警告。
我是 C 的新手。我通过写下 & 和 * 运算符在每一行用英文句子和试错法来完成这项工作。
有两件事我不确定。
A行p0
的初始值不可预知。然而,E 行将一个值赋给由 main 中变量 p0 的值指定的地址。这会导致任何问题吗?如果是,如何解决?
代码使用了很多 *,比如 C 行中的 ***。它可以使用更少的 * 而不会收到 gcc 的警告吗?
谢谢。
#include <stdlib.h>
#include <stdio.h>
void* f(int*** ptr_p) //C
{
int** p = *(ptr_p); //D
*p = malloc(8); //E
*(*p) = 200; //F
(*p)[1] = 4; //G
}
int main(void)
{
int** p0; //A
f(&p0); //B
printf("%d, %d\n",*(*p0), (*p0)[1]);
free(*p0); //H
}
如果你想看英文句子,就在这里。
警告:本人是C新手,不知道说的对不对
第[A]行int** p0;
p0
的值不可预测。
行[B]f(&p0);
&p0
是变量p0
的地址。 f(&p0)
表示调用函数 f
并将 &p0
赋值给函数的第一个参数。
行[C]void* f(int*** ptr_p)
B 行将 &p0
分配给 ptr_p
。这意味着 ptr_p
的值现在等于主函数中变量 p0
的地址。
第[D]行int** p = *(ptr_p);
*(ptr_p)
表示由 ptr_p
的值指定的地址处的值,解释为地址。 ptr_p
的值是主函数中变量p0
的地址,如C行所述。因此,*(ptr_p)
是主函数中变量p0
的值。
p = *(ptr_p);
表示将main函数中p0
的值赋给p
的值
行[E]*(p) = malloc(8);
*(p)
表示p
的值指定地址处的值。 p
的值是 main 中 p0
变量的值,如行 [D] 中所述。那么,*(p)
表示main()
中p0
变量的值指定的地址的值。
malloc(8)
在内存中保留8个字节,return这8个字节的首地址。
整行的意思是将这8个字节的第一个字节的地址赋值为main()
中p0
变量指定的地址的值。
第[F]行*(*p) = 200;
行[G](*p)[1] = 4;
(p)[1]
表示*(p + 1)
(*p)[1]
表示*(*p + 1)
你需要的星星越多越好,所以我简化了你的程序。
#include <stdio.h>
#include <stdlib.h>
int *f(int size) // returns a pointer
{
int *p; // define a pointer
p = malloc(size); // allocate memory to it
if(p == NULL) { // check the result
exit(1); // emergency exit
}
*p = 200; // put a value at p[0];
p[1] = 4; // put a value at p[1];
return p; // return the pointer
}
int main(void)
{
int *p0; // pointer as yet has no value assigned
p0 = f(2 * sizeof *p0); // get memory for 2 ints and initialise it
printf("%d, %d\n", *p0, p0[1]); // show the two ints assigned
free(p0); // release the memory
return 0; // end of program
}
程序输出:
200, 4
除了星数减少外,您的计划还有两个主要变化
函数returns直接一个指针。通过参数设置它需要多一颗星。
请求的内存量是针对数据类型的两个元素,而不是"hard coded"。
此外,您认为可以通过多种方式访问基于指针的数组是正确的。
是的,E 行有问题。实际上,您在 D 行已经遇到麻烦,因为您读取了 p0
的(未定义)值。这在 C 中是被禁止的;它是可怕的 未定义行为 的一部分,这意味着所有的赌注都没有了,编译器在法律上被允许输出它想要的任何东西:一个崩溃的二进制文件,或者打印 "Hello world!" , 随你便。
您正确地看到 p0
应该指向一个 int *
缓冲区,然后才能写入该缓冲区。但是,不需要这种额外的间接级别。 p0
可以是 int *
:
#include <stdlib.h>
#include <stdio.h>
void f(int** ptr_p) //C
{
*ptr_p = malloc(sizeof(int) * 2); //E
(*ptr_p)[0] = 200; //F
(*ptr_p)[1] = 4; //G
}
int main(void)
{
int* p0; //A
f(&p0); //B
printf("%d, %d\n", p0[0], p0[1]);
free(p0); //H
return 0;
}
最后一件事:malloc
可能会失败并且 return NULL
;一个健壮的程序会检查这一点。
以下代码似乎有效。 linux 上的 gcc 5.2.1 没有给出任何警告。
我是 C 的新手。我通过写下 & 和 * 运算符在每一行用英文句子和试错法来完成这项工作。
有两件事我不确定。
A行p0
的初始值不可预知。然而,E 行将一个值赋给由 main 中变量 p0 的值指定的地址。这会导致任何问题吗?如果是,如何解决?
代码使用了很多 *,比如 C 行中的 ***。它可以使用更少的 * 而不会收到 gcc 的警告吗?
谢谢。
#include <stdlib.h>
#include <stdio.h>
void* f(int*** ptr_p) //C
{
int** p = *(ptr_p); //D
*p = malloc(8); //E
*(*p) = 200; //F
(*p)[1] = 4; //G
}
int main(void)
{
int** p0; //A
f(&p0); //B
printf("%d, %d\n",*(*p0), (*p0)[1]);
free(*p0); //H
}
如果你想看英文句子,就在这里。
警告:本人是C新手,不知道说的对不对
第[A]行int** p0;
p0
的值不可预测。
行[B]f(&p0);
&p0
是变量p0
的地址。 f(&p0)
表示调用函数 f
并将 &p0
赋值给函数的第一个参数。
行[C]void* f(int*** ptr_p)
B 行将 &p0
分配给 ptr_p
。这意味着 ptr_p
的值现在等于主函数中变量 p0
的地址。
第[D]行int** p = *(ptr_p);
*(ptr_p)
表示由 ptr_p
的值指定的地址处的值,解释为地址。 ptr_p
的值是主函数中变量p0
的地址,如C行所述。因此,*(ptr_p)
是主函数中变量p0
的值。
p = *(ptr_p);
表示将main函数中p0
的值赋给p
行[E]*(p) = malloc(8);
*(p)
表示p
的值指定地址处的值。 p
的值是 main 中 p0
变量的值,如行 [D] 中所述。那么,*(p)
表示main()
中p0
变量的值指定的地址的值。
malloc(8)
在内存中保留8个字节,return这8个字节的首地址。
整行的意思是将这8个字节的第一个字节的地址赋值为main()
中p0
变量指定的地址的值。
第[F]行*(*p) = 200;
行[G](*p)[1] = 4;
(p)[1]
表示*(p + 1)
(*p)[1]
表示*(*p + 1)
你需要的星星越多越好,所以我简化了你的程序。
#include <stdio.h>
#include <stdlib.h>
int *f(int size) // returns a pointer
{
int *p; // define a pointer
p = malloc(size); // allocate memory to it
if(p == NULL) { // check the result
exit(1); // emergency exit
}
*p = 200; // put a value at p[0];
p[1] = 4; // put a value at p[1];
return p; // return the pointer
}
int main(void)
{
int *p0; // pointer as yet has no value assigned
p0 = f(2 * sizeof *p0); // get memory for 2 ints and initialise it
printf("%d, %d\n", *p0, p0[1]); // show the two ints assigned
free(p0); // release the memory
return 0; // end of program
}
程序输出:
200, 4
除了星数减少外,您的计划还有两个主要变化
函数returns直接一个指针。通过参数设置它需要多一颗星。
请求的内存量是针对数据类型的两个元素,而不是"hard coded"。
此外,您认为可以通过多种方式访问基于指针的数组是正确的。
是的,E 行有问题。实际上,您在 D 行已经遇到麻烦,因为您读取了 p0
的(未定义)值。这在 C 中是被禁止的;它是可怕的 未定义行为 的一部分,这意味着所有的赌注都没有了,编译器在法律上被允许输出它想要的任何东西:一个崩溃的二进制文件,或者打印 "Hello world!" , 随你便。
您正确地看到 p0
应该指向一个 int *
缓冲区,然后才能写入该缓冲区。但是,不需要这种额外的间接级别。 p0
可以是 int *
:
#include <stdlib.h>
#include <stdio.h>
void f(int** ptr_p) //C
{
*ptr_p = malloc(sizeof(int) * 2); //E
(*ptr_p)[0] = 200; //F
(*ptr_p)[1] = 4; //G
}
int main(void)
{
int* p0; //A
f(&p0); //B
printf("%d, %d\n", p0[0], p0[1]);
free(p0); //H
return 0;
}
最后一件事:malloc
可能会失败并且 return NULL
;一个健壮的程序会检查这一点。