【问题标题】:What is wrong with my dynamically allocated array of pointers to structs?我动态分配的指向结构的指针数组有什么问题?
【发布时间】:2016-10-06 04:21:00
【问题描述】:

我有以下程序通过双指针引用数组元素。

typedef struct {
  int num1;
  int num2;
  int num3;
} DATA_SET;

typedef struct {
  int          structID;                                              
  DATA_SET     *data_set_array;  // Pointer to an array of DATA_SET structs
} MY_STRUCT;

int main () {
   MY_STRUCT   *Struct1;
   DATA_SET    **DataSetArray;   // Array of pointers

   Struct1 = malloc(sizeof(MY_STRUCT));
   Struct1->data_set_array = malloc(sizeof(DATA_SET*))  //Allocate mem for the pointer to array of DATA_SETs

   DataSetArray = malloc(sizeof(DATA_SET*) * 2)  // Allocate mem for an array of 2 DATA_SET pointers

   DataSetArray[0] = malloc(sizeof(DATA_SET))    // Allocate mem for the actual DATA_SET struct
   DataSetArray[0]->num1 = 1;
   DataSetArray[0]->num2 = 2;
   DataSetArray[0]->num3 = 3;

   DataSetArray[1] = malloc(sizeof(DATA_SET))    // Allocate mem for the actual DATA_SET struct
   DataSetArray[1]->num1 = 1;
   DataSetArray[1]->num2 = 2;
   DataSetArray[1]->num3 = 3;

   memcpy(Struct1->data_set_array, *DataSetArray, sizeof(DATA_SET*);  //Copy data set array into Struct1

当我在 Struct1 中打印所有数据时,我得到:

   Struct1->data_set_array[0].num1 = 1
   Struct1->data_set_array[0].num2 = 2
   Struct1->data_set_array[0].num3 = 3
   Struct1->data_set_array[1].num1 = 50       //This should be 1
   Struct1->data_set_array[1].num2 = 50       //This should be 2
   Struct1->data_set_array[1].num3 = 65       //This should be 3

似乎是数组中第二个元素的误用/数据损坏。

我知道可能有不同的方法可以做到这一点,但我想熟悉通过双指针引用数组索引。我是否正确分配内存?我感觉 memcpy 不正确。

【问题讨论】:

  • 您为 DataSetArray 分配了两倍于 Struct1->data_set_array 的内存大小,然后复制了一半的数据。
  • 为什么要变量DataSetArray 和一个memcpy?只需使用Struct1->data_set_array - 它会让您的代码更简单。
  • 您的意思是明确修改 Struct1->data_set_array[0] 吗?我不需要为结构分配内存吗?
  • "DATA_SET **DataSetArray; // Array of pointers" 这里的DataSetArray 是指向DATA_SET 的指针。任何地方都没有数组。
  • 我想熟悉如何通过双指针引用数组索引。”这很不清楚,因为它现在没有任何意义。可能是语言问题?无论如何,请更详细地描述您的目标。

标签: c arrays pointers dynamic


【解决方案1】:
Struct1->data_set_array = malloc(sizeof(DATA_SET*)
/*                                              ^ wrong */

DataSetArray = malloc(sizeof(DATA_SET*) * 2)
/*                                   ^ wrong */

您需要使用sizeof(DATA_SET),因为这是结构的实际大小,而不是指向DATA_SET 结构的指针。

您犯了一个错误,即只分配指针大小乘以 2,这在许多情况下可能比您希望的要小。

memcpy(Struct1->data_set_array, *DataSetArray, sizeof(DATA_SET*);

这也是错误的。您必须复制sizeof(DATA_SET)。请记住 sizeof(DATA_SET) 不等于 sizeof(DATA_SET*)。无论指针的类型如何,指针的字节大小都是相同的。

【讨论】:

    【解决方案2】:

    我动态分配的指向结构的指针数组有什么问题?

    DataSetArray 是一个指向 struct 的指针数组,它没有有什么问题。

    问题是另外两件事:

    您不能在指向结构的指针数组上使用memcpy。内存不连续。

    此外,data_set_array 不是指向 struct 的指针数组,因此您试图在不兼容的类型之间进行复制。

    【讨论】:

    • 啊。我应该将 data_set_array 更改为双指针吗? DATA_SET **data_set_array; // 指向 DATA_SET 数组的指针
    • @user1224478 - 这取决于您真正在寻找什么。您希望data_set_array 成为an array of structs 还是希望data_set_array 成为array of pointers to struct?那是两种不同的东西。您当前的代码混合了这些。为了帮助您编写代码,我们首先需要知道您真正想要的。
    【解决方案3】:

    我猜你基本上是想创建一个双维数组。所以基本上你可以做这样的代码

    struct abc {
        int i;
    };
    
    struct abc **arr;
    arr = (struct abc **) malloc(sizeof(struct abc) * 2);
    arr[0] = (struct abc*)malloc(sizeof(struct abc));
    arr[0]->i = 100;
    arr[1] = (struct abc*)malloc(sizeof(struct abc));
    arr[1]->i = 200;
    

    你需要记住的一件事是外部数组只是一个指针,所以它不需要是 sizeof(abc) ,它很可能是 sizeof(int*) / sizeof (void*) 等.

    所以基本上上面的代码可以写成

    struct abc **arr;
    arr = (struct abc **) malloc(sizeof(int *) * 2);
    arr[0] = (struct abc*)malloc(sizeof(struct abc));
    arr[0]->i = 100;
    arr[1] = (struct abc*)malloc(sizeof(struct abc));
    arr[1]->i = 200;
    

    希望这有助于您对代码进行的底层内存管理

    【讨论】:

    • 无论如何,这个arr = (struct abc **) malloc(sizeof(... 应该是arr = malloc(sizeof(struct abc *) * 2); 或者更好/更健壮的arr = malloc(2 * sizeof *arr);
    • 顺便说一句,没有必要在 C 中强制转换 void-pointers,也不建议以任何方式,
    • alk “顺便说一句,没有必要在 C 中强制转换 void-pointers,也没有任何建议”你从哪里得到这些建议?是标准的吗?如果不是,那么它只对编码器而不是编译器无关紧要。顺便说一句,我不确定你在这里想说什么。可能有更好的方法但它与问题无关?
    • C11 标准说,与void-pointers 之间的指针转换是隐式完成的。这与 C++ 不同。
    • 你也可以在这里阅读:stackoverflow.com/questions/1565496/…
    猜你喜欢
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 2021-03-14
    • 2013-04-18
    • 2022-01-14
    • 2021-12-14
    • 1970-01-01
    • 2020-05-17
    相关资源
    最近更新 更多