malloc 和指向指针的指针
malloc and pointers to pointers
我正在尝试了解在使用多级指针时何时需要使用 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
为类型 Person
分配 space。在第二个版本中,我将 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版中**p
需要malloc
space,而我不需要malloc
space *p
?它们都是指向指针的指针?
2) 另外,为什么我不需要 malloc
space for p
in either the 2nd or 3rd version?
3) 在第三个版本中,*p
malloc
的正确大小是多少?在我的 64 位 Mac 上,sizeof(void)
是 1,sizeof(void*)
是 8,两者似乎都有效,但哪个是正确的?
我只是想把这个放在这里做总结:
1) 您确实需要为 *p
分配 space。如果您 运行 使用 valgrind 的第二个程序,您将看到分配大小错误(1 而不是 8); *p
是指向指针的指针,但 **p
不是,它是指向结构的指针。
2) 你确实需要在这两种情况下分配 space,如果你打开警告(无论如何你都不应该关闭),你会收到这个警告:
warning: ‘p’ is used uninitialized in this function [-Wuninitialized] *p = malloc(sizeof(Person));
3) 右边的是void*
。 void*
是一个指针,这意味着它的大小足以包含 64 位计算机中的每个内存地址。如果您的计算机使用的是 32 位系统,它可能会更小。虽然使用
会更好
malloc(sizeof(Person*));
而不是 malloc(sizeof(void*));
因为您已经知道要使用的类型。它不会改变计算机方面的任何东西,但会使代码更清晰。
取消引用一个尚未初始化的指针 (*p
) 在任何情况下都会引发未定义的行为。
在将 space 分配给一个指针时,您通常希望通过通常使用 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;
}
我正在尝试了解在使用多级指针时何时需要使用 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
为类型 Person
分配 space。在第二个版本中,我将 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版中**p
需要malloc
space,而我不需要malloc
space *p
?它们都是指向指针的指针?
2) 另外,为什么我不需要 malloc
space for p
in either the 2nd or 3rd version?
3) 在第三个版本中,*p
malloc
的正确大小是多少?在我的 64 位 Mac 上,sizeof(void)
是 1,sizeof(void*)
是 8,两者似乎都有效,但哪个是正确的?
我只是想把这个放在这里做总结:
1) 您确实需要为 *p
分配 space。如果您 运行 使用 valgrind 的第二个程序,您将看到分配大小错误(1 而不是 8); *p
是指向指针的指针,但 **p
不是,它是指向结构的指针。
2) 你确实需要在这两种情况下分配 space,如果你打开警告(无论如何你都不应该关闭),你会收到这个警告:
warning: ‘p’ is used uninitialized in this function [-Wuninitialized] *p = malloc(sizeof(Person));
3) 右边的是void*
。 void*
是一个指针,这意味着它的大小足以包含 64 位计算机中的每个内存地址。如果您的计算机使用的是 32 位系统,它可能会更小。虽然使用
malloc(sizeof(Person*));
而不是 malloc(sizeof(void*));
因为您已经知道要使用的类型。它不会改变计算机方面的任何东西,但会使代码更清晰。
取消引用一个尚未初始化的指针 (
*p
) 在任何情况下都会引发未定义的行为。在将 space 分配给一个指针时,您通常希望通过通常使用
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;
}