在指向结构的指针内为指向结构的双指针动态分配内存的改进
Improvements to dynamically allocate memory for a double pointer to struct inside a pointer to struct
我写了下面的代码来为嵌套结构动态分配内存:Product **product;
我的代码的目的是让我学习正确或更好的方法来动态分配内存以使用指向结构的双指针在另一个指向结构的指针中。代码运行良好。
问:对代码有什么更正或改进吗?提前感谢您分享您的经验。
typedef struct {
int price;
} Product;
typedef struct {
Product **product;
int id;
} Inventory;
int main() {
int i, j, k, count=0;
int n1=2, n2=3, n3=2;
Inventory *inventory = malloc(n1 * sizeof *inventory);
for (i=0; i<n1; i++) {
inventory[i].product = malloc(n2 * sizeof *inventory[i].product);
for (j=0; j<n2; j++) {
inventory[i].product[j] = malloc(n3 * sizeof *inventory[i].product[j]);
}
}
for (i=0; i<n1; i++) {
for (j=0; j<n2; j++) {
for (k=0; k<n3; k++) {
inventory[i].product[j][k].price = count++;
printf("%d " , inventory[i].product[j][k].price);
}
}
}
return 0;
}
Output: 0 1 2 3 4 5 6 7 8 9 10 11
我尝试使用更大的 n1
、n2
和 n3
,您的代码也能正常工作。
但是有两点需要注意:
1.使用malloc()
分配内存后需要添加free()
2.如果要使用c++编译器(例如g++)编译这段代码,需要转换malloc()
函数返回的指针类型。
以下是我测试的代码。 运行 会花费一些时间:
#include "stdlib.h"
#include "stdio.h"
typedef struct {
int price;
} Product;
typedef struct {
Product **product;
int id;
} Inventory;
int main() {
int i, j, k, count=0;
int n1=525, n2=33, n3=141;
Inventory *inventory = (Inventory*)malloc(n1 * sizeof *inventory);
for (i=0; i<n1; i++) {
inventory[i].product = (Product**)malloc(n2 * sizeof *inventory[i].product);
for (j=0; j<n2; j++) {
inventory[i].product[j] = (Product*)malloc(n3 * sizeof *inventory[i].product[j]);
for (k=0; k<n3; k++) {
inventory[i].product[j][k].price = k*i*j;
}
}
}
for (i=0; i<n1; i++) {
for (j=0; j<n2; j++) {
for (k=0; k<n3; k++) {
printf("%d\n", inventory[i].product[j][k].price);
}
}
}
for (i=0; i<n1; i++) {
for (j=0; j<n2; j++) {
free(inventory[i].product[j]);
}
free(inventory[i].product);
}
free(inventory);
return 0;
}
希望对您有所帮助。
问题是product
是指向指针的指针,所以如果你只打算在Inventory
下使用product
的数组,你必须使用->
表示法而不是 price
的 .
符号。 (请参阅下面的 示例 1)但是,如果您打算实际嵌套结构数组 Product
在您分配的每个 pointer-to-Product
下(即 subproducts
) , 请参阅 示例 2:
注意:每次分配后,必须检查malloc
的return以确保分配成功。 (为简洁起见,在下面的 示例 1 中省略,完整显示在 示例 2 中)
示例 1
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int price;
} Product;
typedef struct {
Product **product;
int id;
} Inventory;
int main () {
int i, j;
int n1 = 2, n2 = 3;
/* allocated / initiaize Inventory and Product */
Inventory *inventory = malloc (n1 * sizeof *inventory);
for (i = 0; i < n1; i++)
{
inventory[i].id = i;
inventory[i].product = malloc (n2 * sizeof *inventory[i].product);
for (j = 0; j < n2; j++)
{
inventory[i].product[j] = malloc (sizeof *inventory[i].product[j]);
inventory[i].product[j]->price = (j + 1) * 2;
}
}
/* print the inventory / procduct price */
for (i = 0; i < n1; i++)
{
printf ("\n product id : %d\n", inventory[i].id);
for (j = 0; j < n2; j++)
{
printf (" price : %d\n", inventory[i].product[j]->price);
}
}
/* free all memory */
for (i = 0; i < n1; i++)
{
for (j = 0; j < n2; j++)
free (inventory[i].product[j]);
free (inventory[i].product);
}
free (inventory);
return 0;
}
输出
$ ./bin/allocate_ptr_in_struct
product id : 0
price : 2
price : 4
price : 6
product id : 1
price : 2
price : 4
price : 6
内存使用错误检查
$ valgrind ./bin/allocate_ptr_in_struct
==10167== Memcheck, a memory error detector
==10167== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==10167== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==10167== Command: ./bin/allocate_ptr_in_struct
==10167==
product id : 0
price : 2
price : 4
price : 6
product id : 1
price : 2
price : 4
price : 6
==10167==
==10167== HEAP SUMMARY:
==10167== in use at exit: 0 bytes in 0 blocks
==10167== total heap usage: 9 allocs, 9 frees, 104 bytes allocated
==10167==
==10167== All heap blocks were freed -- no leaks are possible
==10167==
==10167== For counts of detected and suppressed errors, rerun with: -v
==10167== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
嵌套子产品的分配
示例 2
根据您打算在 **product
下分配嵌套结构的评论,更改很简单:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int price;
} Product;
typedef struct {
Product **product;
int id;
} Inventory;
int main () {
int i, j, k;
int n1 = 2, n2 = 3, n3 = 2;
/* allocated / initiaize Inventory and Product */
Inventory *inventory = malloc (n1 * sizeof *inventory);
if (!inventory) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
for (i = 0; i < n1; i++)
{
inventory[i].id = i;
if (!(inventory[i].product = malloc (n2 * sizeof *inventory[i].product))) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
for (j = 0; j < n2; j++)
{
if (!(inventory[i].product[j] = malloc (n3 * sizeof *inventory[i].product[j]))) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
for (k = 0; k < n3; k++)
inventory[i].product[j][k].price = (j + 1) * 2 * (k + 1);
}
}
/* print the inventory / procduct price */
for (i = 0; i < n1; i++)
{
printf ("\n Inventory id : %d\n", inventory[i].id);
for (j = 0; j < n2; j++)
{
printf ("\n Product[%d]\n", j);
for (k = 0; k < n3; k++)
printf (" subproduct[%d][%d] price : %d\n",
j, k, inventory[i].product[j][k].price);
}
}
/* free all memory */
for (i = 0; i < n1; i++)
{
for (j = 0; j < n2; j++)
free (inventory[i].product[j]);
free (inventory[i].product);
}
free (inventory);
return 0;
}
输出
$ ./bin/allocate_ptr_in_struct
Inventory id : 0
Product[0]
subproduct[0][0] price : 2
subproduct[0][1] price : 4
Product[1]
subproduct[1][0] price : 4
subproduct[1][1] price : 8
Product[2]
subproduct[2][0] price : 6
subproduct[2][1] price : 12
Inventory id : 1
Product[0]
subproduct[0][0] price : 2
subproduct[0][1] price : 4
Product[1]
subproduct[1][0] price : 4
subproduct[1][1] price : 8
Product[2]
subproduct[2][0] price : 6
subproduct[2][1] price : 12
内存使用错误检查
$ valgrind ./bin/allocate_ptr_in_struct
==23024== Memcheck, a memory error detector
==23024== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==23024== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==23024== Command: ./bin/allocate_ptr_in_struct
==23024==
Inventory id : 0
Product[0]
subproduct[0][0] price : 2
subproduct[0][1] price : 4
Product[1]
subproduct[1][0] price : 4
subproduct[1][1] price : 8
Product[2]
subproduct[2][0] price : 6
subproduct[2][1] price : 12
Inventory id : 1
Product[0]
subproduct[0][0] price : 2
subproduct[0][1] price : 4
Product[1]
subproduct[1][0] price : 4
subproduct[1][1] price : 8
Product[2]
subproduct[2][0] price : 6
subproduct[2][1] price : 12
==23024==
==23024== HEAP SUMMARY:
==23024== in use at exit: 0 bytes in 0 blocks
==23024== total heap usage: 9 allocs, 9 frees, 128 bytes allocated
==23024==
==23024== All heap blocks were freed -- no leaks are possible
==23024==
==23024== For counts of detected and suppressed errors, rerun with: -v
==23024== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
我写了下面的代码来为嵌套结构动态分配内存:Product **product;
我的代码的目的是让我学习正确或更好的方法来动态分配内存以使用指向结构的双指针在另一个指向结构的指针中。代码运行良好。
问:对代码有什么更正或改进吗?提前感谢您分享您的经验。
typedef struct {
int price;
} Product;
typedef struct {
Product **product;
int id;
} Inventory;
int main() {
int i, j, k, count=0;
int n1=2, n2=3, n3=2;
Inventory *inventory = malloc(n1 * sizeof *inventory);
for (i=0; i<n1; i++) {
inventory[i].product = malloc(n2 * sizeof *inventory[i].product);
for (j=0; j<n2; j++) {
inventory[i].product[j] = malloc(n3 * sizeof *inventory[i].product[j]);
}
}
for (i=0; i<n1; i++) {
for (j=0; j<n2; j++) {
for (k=0; k<n3; k++) {
inventory[i].product[j][k].price = count++;
printf("%d " , inventory[i].product[j][k].price);
}
}
}
return 0;
}
Output: 0 1 2 3 4 5 6 7 8 9 10 11
我尝试使用更大的 n1
、n2
和 n3
,您的代码也能正常工作。
但是有两点需要注意:
1.使用malloc()
分配内存后需要添加free()
2.如果要使用c++编译器(例如g++)编译这段代码,需要转换malloc()
函数返回的指针类型。
以下是我测试的代码。 运行 会花费一些时间:
#include "stdlib.h"
#include "stdio.h"
typedef struct {
int price;
} Product;
typedef struct {
Product **product;
int id;
} Inventory;
int main() {
int i, j, k, count=0;
int n1=525, n2=33, n3=141;
Inventory *inventory = (Inventory*)malloc(n1 * sizeof *inventory);
for (i=0; i<n1; i++) {
inventory[i].product = (Product**)malloc(n2 * sizeof *inventory[i].product);
for (j=0; j<n2; j++) {
inventory[i].product[j] = (Product*)malloc(n3 * sizeof *inventory[i].product[j]);
for (k=0; k<n3; k++) {
inventory[i].product[j][k].price = k*i*j;
}
}
}
for (i=0; i<n1; i++) {
for (j=0; j<n2; j++) {
for (k=0; k<n3; k++) {
printf("%d\n", inventory[i].product[j][k].price);
}
}
}
for (i=0; i<n1; i++) {
for (j=0; j<n2; j++) {
free(inventory[i].product[j]);
}
free(inventory[i].product);
}
free(inventory);
return 0;
}
希望对您有所帮助。
问题是product
是指向指针的指针,所以如果你只打算在Inventory
下使用product
的数组,你必须使用->
表示法而不是 price
的 .
符号。 (请参阅下面的 示例 1)但是,如果您打算实际嵌套结构数组 Product
在您分配的每个 pointer-to-Product
下(即 subproducts
) , 请参阅 示例 2:
注意:每次分配后,必须检查malloc
的return以确保分配成功。 (为简洁起见,在下面的 示例 1 中省略,完整显示在 示例 2 中)
示例 1
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int price;
} Product;
typedef struct {
Product **product;
int id;
} Inventory;
int main () {
int i, j;
int n1 = 2, n2 = 3;
/* allocated / initiaize Inventory and Product */
Inventory *inventory = malloc (n1 * sizeof *inventory);
for (i = 0; i < n1; i++)
{
inventory[i].id = i;
inventory[i].product = malloc (n2 * sizeof *inventory[i].product);
for (j = 0; j < n2; j++)
{
inventory[i].product[j] = malloc (sizeof *inventory[i].product[j]);
inventory[i].product[j]->price = (j + 1) * 2;
}
}
/* print the inventory / procduct price */
for (i = 0; i < n1; i++)
{
printf ("\n product id : %d\n", inventory[i].id);
for (j = 0; j < n2; j++)
{
printf (" price : %d\n", inventory[i].product[j]->price);
}
}
/* free all memory */
for (i = 0; i < n1; i++)
{
for (j = 0; j < n2; j++)
free (inventory[i].product[j]);
free (inventory[i].product);
}
free (inventory);
return 0;
}
输出
$ ./bin/allocate_ptr_in_struct
product id : 0
price : 2
price : 4
price : 6
product id : 1
price : 2
price : 4
price : 6
内存使用错误检查
$ valgrind ./bin/allocate_ptr_in_struct
==10167== Memcheck, a memory error detector
==10167== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==10167== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==10167== Command: ./bin/allocate_ptr_in_struct
==10167==
product id : 0
price : 2
price : 4
price : 6
product id : 1
price : 2
price : 4
price : 6
==10167==
==10167== HEAP SUMMARY:
==10167== in use at exit: 0 bytes in 0 blocks
==10167== total heap usage: 9 allocs, 9 frees, 104 bytes allocated
==10167==
==10167== All heap blocks were freed -- no leaks are possible
==10167==
==10167== For counts of detected and suppressed errors, rerun with: -v
==10167== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
嵌套子产品的分配
示例 2
根据您打算在 **product
下分配嵌套结构的评论,更改很简单:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int price;
} Product;
typedef struct {
Product **product;
int id;
} Inventory;
int main () {
int i, j, k;
int n1 = 2, n2 = 3, n3 = 2;
/* allocated / initiaize Inventory and Product */
Inventory *inventory = malloc (n1 * sizeof *inventory);
if (!inventory) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
for (i = 0; i < n1; i++)
{
inventory[i].id = i;
if (!(inventory[i].product = malloc (n2 * sizeof *inventory[i].product))) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
for (j = 0; j < n2; j++)
{
if (!(inventory[i].product[j] = malloc (n3 * sizeof *inventory[i].product[j]))) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
for (k = 0; k < n3; k++)
inventory[i].product[j][k].price = (j + 1) * 2 * (k + 1);
}
}
/* print the inventory / procduct price */
for (i = 0; i < n1; i++)
{
printf ("\n Inventory id : %d\n", inventory[i].id);
for (j = 0; j < n2; j++)
{
printf ("\n Product[%d]\n", j);
for (k = 0; k < n3; k++)
printf (" subproduct[%d][%d] price : %d\n",
j, k, inventory[i].product[j][k].price);
}
}
/* free all memory */
for (i = 0; i < n1; i++)
{
for (j = 0; j < n2; j++)
free (inventory[i].product[j]);
free (inventory[i].product);
}
free (inventory);
return 0;
}
输出
$ ./bin/allocate_ptr_in_struct
Inventory id : 0
Product[0]
subproduct[0][0] price : 2
subproduct[0][1] price : 4
Product[1]
subproduct[1][0] price : 4
subproduct[1][1] price : 8
Product[2]
subproduct[2][0] price : 6
subproduct[2][1] price : 12
Inventory id : 1
Product[0]
subproduct[0][0] price : 2
subproduct[0][1] price : 4
Product[1]
subproduct[1][0] price : 4
subproduct[1][1] price : 8
Product[2]
subproduct[2][0] price : 6
subproduct[2][1] price : 12
内存使用错误检查
$ valgrind ./bin/allocate_ptr_in_struct
==23024== Memcheck, a memory error detector
==23024== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==23024== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==23024== Command: ./bin/allocate_ptr_in_struct
==23024==
Inventory id : 0
Product[0]
subproduct[0][0] price : 2
subproduct[0][1] price : 4
Product[1]
subproduct[1][0] price : 4
subproduct[1][1] price : 8
Product[2]
subproduct[2][0] price : 6
subproduct[2][1] price : 12
Inventory id : 1
Product[0]
subproduct[0][0] price : 2
subproduct[0][1] price : 4
Product[1]
subproduct[1][0] price : 4
subproduct[1][1] price : 8
Product[2]
subproduct[2][0] price : 6
subproduct[2][1] price : 12
==23024==
==23024== HEAP SUMMARY:
==23024== in use at exit: 0 bytes in 0 blocks
==23024== total heap usage: 9 allocs, 9 frees, 128 bytes allocated
==23024==
==23024== All heap blocks were freed -- no leaks are possible
==23024==
==23024== For counts of detected and suppressed errors, rerun with: -v
==23024== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)