【问题标题】:Multiple arrays with malloc使用 malloc 的多个数组
【发布时间】:2013-12-23 13:19:16
【问题描述】:

我正在初始化一个名为 Array 的结构,它由一个 Items 数组和一个用于跟踪 Items 数量的 int 组成。

  typedef struct anything{
    char text[MAXI];
    int any;
  }Item;

  typedef struct array{
    Item arr[0];
    int size;
  }Array;

为了初始化数组,我使用 malloc 并返回指针。

Array create(){
    Array *p1 = malloc(sizeof(Array));
    p1->size = 0;
    return *p1;
}

我的问题是有些函数是为2个数组设计的,比如交集:

Array intersection(Array S,Array T){
    int i, j;
    Array I = create();
    for(i=0; i<(S.size); i++){
        for(j=0; j<(T.size); j++){
            if((compStructs(S.arr[i], T.arr[j])) == true)
                add(I, S.arr[i]);
        }
    }
    return I;
}

根据这段代码,如果我执行 create() 两次,我会丢失指向第一个数组的指针。我可以在主程序中做些什么来防止这种情况发生,或者我可以对当前功能做哪些修改?

编辑:添加添加项目功能:

void add(Array S,Item x){

bool rep = false;
    int i = 0;
    for(i = 0; i<(S.size); i++){
        if(compStructs(x,S.arr[i]) == true)
            rep = true;
    }
    if(rep == false){
            Item *p2 = realloc(S.arr, sizeof(Item));
            *p2 = x;
            (S.size)++;
    }
    else
        printf("The item is already in the set.");

}

我的主要问题是我不确定如何调用两个要根据用户请求创建的单独数组。该程序正在构建中,但目前它看起来像这样:

#include "array.h"
Item x;

void arraymenu(){
    char inp;
    while((inp = getchar())!= '\n'){
        printf("a. To Create a new Array\n"
                "b. To Add a new Item\n"
                "c. To Remove an Item\n"
                "d. To Clear all contents of the Array\n"
                "e. To Get the size of the Array\n"
                "f. To Get a list of the number of elements of your choice\n"
                "g. To Check whether the array is empty\n"
                "h. To Get the union of two sets\n"
                "i. To Get the intersection of two sets\n"
                "j. To Get the difference of two sets\n"
                "k. To Check if a set is the subset of the other one\n"
                "l. To map a function to all Items of an Array\n"
                "m. To apply a function to all Items of an Array\n"
                "n. To store the Array in a File\n"
                "o. To load the Array from a File\n"   );

        switch(inp){
            case 'a' :  printf("Array A has been created.");
                        Array A = create();
                        break;

            case 'b' :  printf("Enter any integer, followed by any string.");
                        scanf("%d", &x.any);
                        scanf("%s", &x.text);
                        add(A, x);
                        break;

            case 'c' :  printf("Enter the integer and string you wish to remove ");
                        scanf("%d", &x.any);
                        scanf("%s", &x.text);
                        removee(A,x);
                        break;
        }
    }
}

【问题讨论】:

  • 为什么数组后面有大小字段?而且你不想用更大的尺寸 malloc 它,而不是一个有足够空间容纳零元素的数组吗?
  • size 字段用于知道 Item arr[] 的大小。我正在使用带有 0 个元素的 malloc,因为我在另一个函数中使用 realloc 来添加项目。如果需要,将对其进行编辑。
  • 不想听起来傲慢,您可能想了解 pointersarrays Item arr[0] 的区别(和要点)真的没有意义。另外:malloc 包装函数应该,IMO 返回 malloc 返回的内容:指针
  • 每次调用add 时,您都会将arr 重新分配给sizeof(Item)...1 项...如果您想要更多项,则必须将大小乘以项数跨度>
  • @user2035045:你不明白:你没有添加任何东西看到我的回答的结尾:realloc需要指定新的总大小 i> 你需要:realloc(void *, (current_size + add_size) * sizeof(type));

标签: c arrays data-structures struct


【解决方案1】:

基本上,您需要返回一个指针(顺便说一句,编译 return *ptr 应该在编译时给出警告,添加 -Wall ,并且不要忽略编译器告诉你的内容):

Array *create()
{
    Array *a_ptr = malloc(sizeof(*a_ptr));
    if (a_ptr == NULL) exit (EXIT_FAILURE);//failed to allocate memory
    a_ptr->size = 0;
    return a_ptr;
}

这样称呼:

Array *S, *T;
S = create();
T = create();

现在您已经准备好使用 2 个数组了。请注意,您需要或者取消引用这些指针,或者始终对它们使用间接运算符:

(*S).size = 1;
//or
S->size += 123;

您可能还想将intersection 更改为:

Array *intersection(Array *S,Array *T)
{
    int i, j;
    Array *I = create();
    for(i=0; i<(S->size); ++i)
    {
        for(j=0; j<(T->size); ++j)
            if(compStructs(S.arr[i], T.arr[j])) add(I, S.arr[i]);
        }
    }
    return I;
}

当然,一旦你完成了所有这些Array 结构,你也必须free() 他们。

compStructsadd 而言,我希望您也必须处理这些功能。当您使用它时,也许可以更改结构以更好地适应您的使用方式:

typedef struct array
{
    Item *arr;
    size_t size;//size_t makes more sense here
  }Array;

当然,这反过来又需要在free-ing 内存时做更多的工作,因此建议使用通用的 free 函数:

void free_array(Array **a)
{//pointer to pointer
    while((*a)->size--) free((*a)->arr+(*a)->size);
    free(*a);
    *a = NULL;//NULL pointers are safer
}
//call like so:
free_array(&Array_ptr);//yes, address of pointer

realloc 调用应该类似于:

realloc(a->arr, (a->size + 1)*sizeof(*(a->arr)));
a->size += 1;

【讨论】:

    【解决方案2】:
    typedef struct array{
        int size;
        Item arr[];
    }Array;
    
    Array *create(int size){
        Array *p1 = malloc(sizeof(Array) + size*sizeof(Item));
        if(p1)p1->size = size;
        //return *p1;//memory leak
        return p1;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-14
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 2019-04-18
      • 2023-03-11
      • 2012-12-10
      相关资源
      最近更新 更多