malloc和指针指针

Idr*_*Idr 2 c malloc pointers pointer-to-pointer

我正在尝试理解何时需要在使用多级指针时使用malloc.例如,

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    typedef struct {
        char first[10];
        char last[10];
    } Person;

    Person *p;

    p = malloc(sizeof(Person));
    strcpy(p->first, "John");
    strcpy(p->last, "Doe");

    printf("First: %s Last:%s\n", p->first, p->last);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我正在使用的第一个版本中Person *p,我只使用malloc为类型分配空间Person.在第二个版本中,我将Person *p改为Person **p

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    typedef struct {
        char first[10];
        char last[10];
    } Person;

    Person **p;

    *p = malloc(sizeof(Person));
    strcpy((*p)->first, "John");
    strcpy((*p)->last, "Doe");

    printf("First: %s Last:%s\n", (*p)->first, (*p)->last);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

malloc即使现在有另一个指针,我仍然只使用一个.

在第三个版本中,我将使用 Person ***p

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    typedef struct {
        char first[10];
        char last[10];
    } Person;

    Person ***p;

    *p = malloc(sizeof(void));
    **p = malloc(sizeof(Person));
    strcpy((**p)->first, "John");
    strcpy((**p)->last, "Doe");

    printf("First: %s Last:%s\n", (**p)->first, (**p)->last);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题:

1)为什么我需要在第3版中使用malloc空格**p,但我不需要malloc空格*p?它们都是指针的指针?

2)另外,为什么我不需要在第2版或第3版中留出malloc空间p

3)在第三个版本中,malloc适合的尺寸是*p多少?在我的64位Mac上,它sizeof(void)是1,而它sizeof(void*)是8,两者似乎都可以工作但是正确的是什么?

alk*_*alk 7

  1. *p在任何情况下,取消引用尚未初始化的指针 ( ) 都会引发未定义的行为。

  2. 当为指针分配空间时,您通常希望通过通常使用sizeof运算符为其分配内存,其指向的大小。后一种情况是 1. 允许编码的唯一例外*p

所以第三个例子可能看起来像这样

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
        char first[10];
        char last[10];
} Person;

int main(void) {
    Person ***p;

    p = malloc(sizeof *p); 
    *p = malloc(sizeof **p);
    **p = malloc(sizeof ***p);
    strcpy((**p)->first, "John");
    strcpy((**p)->last, "Doe");

    printf("First: %s Last:%s\n", (**p)->first, (**p)->last);

    free(**p);
    free(*p);
    free(p);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)


log*_*inn 5

我将在此总结一下:

1)你需要为空间分配空间*p.如果你用valgrind运行你的第二个程序,你会看到一个alloc size(1而不是8)的错误; *p是指向指针的指针,但**p不是,它是指向结构的指针.

2)你需要在两种情况下分配空间,如果你打开警告(你永远不应该关闭它),你会得到这个警告:

warning: ‘p’ is used uninitialized in this function [-Wuninitialized] *p = malloc(sizeof(Person));
Run Code Online (Sandbox Code Playgroud)

3)正确的是void*.void*是一个指针,这意味着它的大小足以包含64位计算机中的每个内存地址.如果您的计算机使用32位系统,它可能会更小.虽然使用起来会更好

malloc(sizeof(Person*)); 代替 malloc(sizeof(void*));

因为您已经知道要使用的类型.它不会改变任何计算机,但会使代码更清晰.