在一个函数中分配内存并在另一个函数中使用它

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

除了星数减少外,您的计划还有两个主要变化

  1. 函数returns直接一个指针。通过参数设置它需要多一颗星。

  2. 请求的内存量是针对数据类型的两个元素,而不是"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;一个健壮的程序会检查这一点。