简体   繁体   English

如何在运行时动态增加任何结构对象的大小?

[英]How to dynamically increase size of any structure objects during runtime?

I am a bit of a beginner in C language.我是 C 语言的初学者。 I was trying out a task of dynamically reallocating memory as the input comes through(although for this test I am doing a normal task, later will try to scale it up).我正在尝试在输入通过时动态重新分配内存的任务(虽然对于这个测试我正在做一个正常的任务,稍后会尝试扩大它)。 the issue I am facing is I am unable to access the memory while writing into it.我面临的问题是在写入内存时无法访问内存。 Can anyone please help me understand where I am going wrong in this code.任何人都可以帮助我理解我在这段代码中哪里出错了。 thanks in advance.提前致谢。

code:代码:

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

struct ai {
    int* a;
    char* b;
};

int main()
{
    struct ai *test;
    test = (struct ai*) malloc(sizeof(struct ai));
    test[0].a = (int*)malloc(sizeof(int));
    test[0].b = (char*)malloc(sizeof(char));

    /// storing info

    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            test[i].a[j] = j;
            test[i].b[j] = 65 + j;
            test[i].a = (int *) realloc(test[i].a, (j + 2) * sizeof(int));
            test[i].b = (char*) realloc(test[i].b, (j + 2) * sizeof(char));
        }
        test = (struct ai*)realloc(test, (i + 2) * sizeof(struct ai));
    }

    // printing the block out

    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            printf("%d , %c\n", test[i].a[j], test[i].b[j]);
        }
    }
    return 0;
} ```

You have missing initialization of your pointers and some other issues...您缺少指针的初始化和其他一些问题...

int main()
{
    struct ai *test;
    test = (struct ai*) malloc(sizeof(struct ai));
    test[0].a = (int*)malloc(sizeof(int));
    test[0].b = (char*)malloc(sizeof(char));

In C you should not cast the result of malloc .在 C 中,您不应malloc的结果。 In best case it is useless.在最好的情况下它是无用的。 In worst case it hides real problems.在最坏的情况下,它隐藏了真正的问题。

    /// storing info

    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            test[i].a[j] = j;
            test[i].b[j] = 65 + j;

Here comes the reason for your segmentation fault: You do not have any memory reserved for a and b except for the first element test[0] .这是您的分段错误的原因:除了第一个元素test[0]之外,您没有为ab保留任何内存。 All other array elements test[i] do not contain any useful data.所有其他数组元素test[i]不包含任何有用的数据。 Dereferencing these pointers is undefined behaviour.取消引用这些指针是未定义的行为。

You must allocate memory for each field after you enlarged your array.扩大数组后,您必须为每个字段分配内存。


            test[i].a = (int *) realloc(test[i].a, (j + 2) * sizeof(int));
            test[i].b = (char*) realloc(test[i].b, (j + 2) * sizeof(char));

You should never assign the return value of realloc to the same variable that you passed into the function.永远不要将realloc的返回值分配给传递给函数的同一个变量。 In case of an error you will get NULL return value and then your initiali pointer is lost.如果出现错误,您将获得NULL返回值,然后您的初始指针丢失。

Also here: don't cast for realloc as well.也在这里:不要为realloc投射。

        }
        test = (struct ai*)realloc(test, (i + 2) * sizeof(struct ai));

Same here: Don't assign to same variable and don't cast the result of realloc .此处相同:不要分配给相同的变量,也不要realloc的结果。

Finally: Here goes the missing part:最后:这是缺失的部分:

        test[i+1].a = malloc(sizeof(*test[0].a));
        test[i+1].b = malloc(sizeof(*test[0].b));
    }

Of course you should check all return values for error results.当然,您应该检查所有返回值的错误结果。

Not related to the segmentation fault, but still worth to fix: You increment the size of each array after you used the last element.与分段错误无关,但仍然值得修复:在使用最后一个元素后增加每个数组的大小。 This prepares the new element for being filled in next iteration of the loops.这为在循环的下一次迭代中填充新元素做好了准备。 But in case of the last iteration it allocated an unused element for both the intern pointers a and b as well as the outer array test .但是在最后一次迭代的情况下,它为内部指针ab以及外部数组test分配了一个未使用的元素。

You will have some unused elements:您将有一些未使用的元素:

test[0].a[4]
test[0].b[4]
test[1].a[4]
test[1].b[4]
test[2].a[0]
test[2].b[0]

An improved solution could look like this (not tested)改进的解决方案可能如下所示(未经测试)

I start with each pointer being NULL and use realloc right before the new element is used to avoid the extra elements.我从每个指针都为NULL开始,并在使用新元素之前使用realloc以避免额外的元素。

int main(void)
{
    struct ai *test = NULL
    void *tmp;

    // storing info
    for (int i = 0; i < 2; i++)
    {
        tmp = realloc(test, (i+1) * sizeof(*test))
        if (tmp == NULL)
            exit(1);

        test = tmp;
        test[i].a = NULL;
        test[i].b = NULL;

        for (int j = 0; j < 4; j++)
        {
            tmp = realloc(test[i].a, (j+1) * sizeof(test[i].a[0]));
            if (tmp == NULL)
                exit(1);
            test[i].a = tmp;

            tmp = realloc(test[i].b, (j+1) * sizeof(test[i].b[0]));
            if (tmp == NULL)
                exit(1);
            test[i].b = tmp;

            test[i].a[j] = j;
            test[i].b[j] = 65 + j;
        }
    }

    // printing the block out
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            printf("%d , %c\n", test[i].a[j], test[i].b[j]);
        }
    }
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM