【问题标题】:Simulating a List with array用数组模拟列表
【发布时间】:2017-06-13 10:16:37
【问题描述】:

早上好! 我必须处理一个模拟列表的结构数组(全局变量)。实际中,每次调用方法,都要增加数组1的大小,插入到新的struct中。

由于数组大小是静态的,我的想法是使用这样的指针:

  1. 结构数组被声明为指向第二个结构数组的指针。
  2. 每次调用increaseSize()方法时,都会将旧数组的内容复制到一个新的n+1数组中。
  3. 全局数组指针更新为指向新数组

理论上,解决方案似乎很简单……但我是 c 的菜鸟。哪里错了?

 struct task {
     char title[50];
     int execution;
     int priority;
    };

    struct task tasks = *p;


 int main() {
    //he will call the increaseSize() somewhere...
}

void increaseSize(){

    int dimension = (sizeof(*p) / sizeof(struct task));

    struct task newTasks[dimension+1];

    for(int i=0; i<dimension; i++){

        newTasks[i] = *(p+i);

    }

    free(&p);

    p = newTasks;
}

【问题讨论】:

  • sizeof(*p) / sizeof(struct task) 看起来很可疑
  • struct task tasks = *p; p 是什么?
  • 顺便说一句,链表是你想要的实现细节——你想做的只是一个list。使用数组执行此操作实际上意味着malloc() 这个数组和realloc() 它在增长时是必要的。
  • 披露bla bla blalinked listarray 这两个词是矛盾的。
  • p 在哪里声明?但无论如何,p = newTasks;工作。

标签: c arrays memory struct


【解决方案1】:

你在这里混淆了很多!

int dimension = (sizeof(*p) / sizeof(struct task));

p 是一个指针,*p 指向一个struct task,所以sizeof(*p) 将等于sizeof(struct task),并且维度总是1...

在这种情况下您不能使用 sizeof。您必须将大小(元素数量)存储在单独的变量中。

struct task newTasks[dimension+1];

这将创建一个新数组,是的——但作用域是当前函数的本地范围(通常,它是在堆栈上分配的)。这意味着一旦你离开你的函数,数组就会被再次清理。

您需要在堆上创建数组。您需要使用 malloc 函数(或 calloc 或 realloc)。

另外,我建议不要将数组增加 1,而是复制其大小。不过,您还需要存储 then 中包含的元素数量。

综合起来:

struct task* p;
size_t count;
size_t capacity;

void initialize()
{
    count = 0;
    capacity = 16;
    p = (struct task*) malloc(capacity * sizeof(struct task));
    if(!p)
        // malloc failed, appropriate error handling!
}

void increase()
{
    size_t c = capacity * 2;
    // realloc is very convenient here:
    // if allocation is successful, it copies the old values
    // to the new location and frees the old memory, so nothing
    // so nothing to worry about except for allocation failure
    struct task* pp = realloc(p, c * sizeof(struct task));
    if(pp)
    {
        p = pp;
        capacity = c;
    }
    // else: apprpriate error handling
}

最后,作为完成:

void push_back(struct task t)
{
    if(count == capacity)
        increase();
    p[count++] = t;
}

删除元素留给您 - 您必须将后续元素全部复制到少一个位置,然后减少计数。

【讨论】:

  • 这将创建一个新数组,是的,但在堆栈上我认为更好的措辞是它将创建一个具有函数本地范围的数组。 C 标准没有堆栈。
  • @AjayBrahmakshatriya 我认为这是一个更糟糕的措辞。使用这种仅标准的行话会使其更难理解(尤其是对于像 OP 这样显然是初学者的人),并且它所做的细微差别在这里无关紧要。即使它可能没有被分配到堆栈上,解释它好像它是无害的。
猜你喜欢
  • 1970-01-01
  • 2023-03-29
  • 2018-03-11
  • 2011-09-12
  • 1970-01-01
  • 2014-04-26
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多