【问题标题】:Dynamically allocate array in C struct response incorrect?在 C 结构响应中动态分配数组不正确?
【发布时间】:2020-12-14 22:04:20
【问题描述】:

我正在尝试在 C 结构中创建两个动态分配的数组

typedef struct {
    int count1;
    int count2;
    int *array1;
    int *array2;
    int check;
} __attribute__ ((packed)) test_T;

int main() {
    int data[8] = { 2, 3, 20, 21, 30, 31, 32, 100 };

    test_T *s_t = malloc(sizeof(s_t));
    s_t->array1 = malloc(sizeof(int) * s_t->count1);
    s_t->array2 = malloc(sizeof(int) * s_t->count2);

    s_t = (test_T *)data;
 
    printf("%d\n", s_t->check);

    return 0;
}

array1array2 的大小都是未知的,分别取决于 count1count2

我的结构数据定义在main 函数中,并将数据放入我的结构中。 问题是结构中的check 成员始终是32,但我希望这个值是100。 任何帮助表示赞赏。

【问题讨论】:

  • test_T *s_t = malloc(sizeof(s_t)); --> test_T *s_t = malloc(sizeof(*s_t));
  • s_t = (test_T *)data;..那你为什么要malloc()
  • 概念上的问题太多了......你能准确说出你想要实现的目标吗?似乎是 X-Y 问题。
  • 你正在将数字转换为指针,sizeof(test_T) 绝对不是 8。
  • s_t = (test_T *)data; 没有任何意义。请进一步澄清您的问题。

标签: arrays c memory dynamic malloc


【解决方案1】:

你的代码有很多问题:

  • __attribute__((packed)) 是特定于系统的 hack。除非您知道自己在做什么并认为绝对有必要,否则您不应该使用此类非便携的东西。

  • 第一个malloc() 的大小不正确:test_T *s_t = malloc(sizeof(s_t)); 应该是

      test_T *s_t = malloc(sizeof(*s_t));
    
  • s_t->count1s_t->count2 必须在使用前进行初始化。 malloc() 返回的对象是未初始化的,所以所有的结构成员都是未初始化的。目前还不清楚这些成员的初始值应该是什么,8 似乎是合理的。

  • s_t->check 未初始化。如果这是预期值,则应将其初始化为 100

  • s_t = (test_T *)data; 是假的:如果你想要的话,你应该将 data 中的值复制到数组中。

这是修改后的版本:

#include <stdio.h>
#include <stdlib.h>

typedef struct test_T {
    int count1;
    int count2;
    int *array1;
    int *array2;
    int check;
} test_T;

int main() {
#define DATA_COUNT  8
    int data[DATA_COUNT] = { 2, 3, 20, 21, 30, 31, 32, 100 };

    test_T *s_t = malloc(sizeof(*s_t));
    s_t->count1 = DATA_COUNT;
    s_t->count2 = DATA_COUNT;
    s_t->array1 = malloc(sizeof(int) * s_t->count1);
    s_t->array2 = malloc(sizeof(int) * s_t->count2);
    s_t->check = 100;

    for (int i = 0; i < DATA_COUNT; i++) {
        s_t->array2[i] = s_t->array1[i] = data[i];
    }
 
    printf("%d\n", s_t->check);

    return 0;
} 

【讨论】:

  • 您可以使用memcpy() 来处理数组。
【解决方案2】:

您的代码中有多个错误,但在此答案中只有一个响应其中之一:指针与数组

我认为您误解了指针和结构的工作原理。 array1 是一个指针。在 AMD64 上,指针总是 8 个字节。这不取决于它们指向的位置。在 AMD64 上,当编译器不添加一些填充时,您的 Test_T 将使用 28 个字节。 当您分配内存并将指针存储在array1 中时,这意味着array1 现在指向您使用malloc() 保留的内存区域。 array1array2 都是数组,它们是指针。也许你为他们选择了一个不那么容易引起误解的名字?

array1 和 array2 的大小都是未知的

这是错误的。它们是指针,它们的大小是已知的。不知道的是指向的内存区域的大小。这个内存区域可以作为数组使用,array1不是数组。

如果你想在你的结构中有一个变量数组,你必须将一个数组作为最后一个元素放置,没有大小信息,当你为结构保留内存时,你必须在最后添加数组的空间和结构.一个结构体中只能放置一个变量数组。 其他的都需要用指针添加。

像这样:

#include <stdlib.h>

struct Test_T
{
    int someOtherData;
    size_t count;
    int variableArray[];
};

int main(void)
{
    size_t count=5;
    struct Test_T *s_t=malloc(sizeof(*s_t)+sizeof(int)*count);
    //skipped malloc error handling, but you should do that in real programs 
    s_t->count=count;
    // .. some more code should be placed here ...
    free(s_t); //do not forget to free your allocated memory
}

【讨论】:

    猜你喜欢
    • 2012-01-22
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    • 2021-10-30
    相关资源
    最近更新 更多