对指向struct的指针内的struct的双指针动态分配内存的改进

时间:2015-04-26 04:32:12

标签: c pointers struct

我编写了下面的代码,为嵌套结构动态分配内存:Product **product;我的代码的目的是让我学习正确或更好的方法来动态分配内存,以便使用指向另一个内部结构的双指针指向struct的指针。代码运行正常。

问题:代码的任何更正或改进?提前感谢您分享您的经验。

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

2 个答案:

答案 0 :(得分:1)

我尝试使用较大的n1n2n3,您的代码也可以使用。

但这里有两点需要注意:

1。您需要在使用free()分配内存后添加malloc()
2. 如果您想使用c ++编译器(例如,g ++)来编译此代码,则需要转换指针&#39; 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;
}

希望它有所帮助。

答案 1 :(得分:-1)

问题是product是指向指针的指针,因此如果您打算只在product下使用Inventory数组,则必须使用->表示法而不是.的{​​{1}}符号。 (参见下面的示例1 )但是,如果您打算在您分配的每个price下实际嵌套一个struct Product数组(即pointer-to-Product),请参阅< strong>示例2 :

注意:每次分配后,您必须检查subproducts的返回,以确保分配成功。 (为简洁起见,在示例1 中省略,在示例2 中完整显示)

示例1

malloc

<强>输出

#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

嵌套子产品的分配

示例2

根据您打算在$ 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) 下分配嵌套结构的注释,更改很简单:

**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