6

我试图了解在使用多级指针时何时需要使用 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;
}

在我使用的第一个版本中Person *p,我只用于malloc为 type 分配空间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;
}

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;
}

我的问题:

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

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

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

4

2 回答 2

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;
}
于 2015-12-26T15:00:11.483 回答
5

我只是把这个放在这里总结一下:

1)您确实需要为*p. 如果你用 valgrind 运行你的第二个程序,你会看到分配大小的错误(1 而不是 8);*p是指向指针的指针,但**p不是,它是指向结构的指针。

2)您确实需要在这两种情况下分配空间,如果您打开警告(无论如何都不应该关闭),您将收到以下警告:

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

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

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

由于您已经知道要使用的类型。它不会改变任何计算机方面的东西,但会使代码更清晰。

于 2015-12-26T11:58:46.107 回答