Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的动态数组函数-设置容量并创建更大的数组_C_Dynamic Arrays_Capacity - Fatal编程技术网

C中的动态数组函数-设置容量并创建更大的数组

C中的动态数组函数-设置容量并创建更大的数组,c,dynamic-arrays,capacity,C,Dynamic Arrays,Capacity,我正在用C语言为一个动态数组构建函数。在需要扩展数组容量之前,在大多数情况下,它们似乎工作得很好。我的功能似乎有两个问题(u dynArrSetCapacity) /* Resizes the underlying array to be the size cap param: v pointer to the dynamic array param: cap the new desired capacity pre: v is not null post:

我正在用C语言为一个动态数组构建函数。在需要扩展数组容量之前,在大多数情况下,它们似乎工作得很好。我的功能似乎有两个问题(u dynArrSetCapacity)

/* Resizes the underlying array to be the size cap

param:  v       pointer to the dynamic array
param:  cap     the new desired capacity
pre:    v is not null
post:   v has capacity newCap
*/
void _dynArrSetCapacity(DynArr *v, int newCap)
{
    assert(v != NULL);
    struct DynArr largerArray; /*create a new dynamic array*/
    initDynArr(&largerArray, newCap); /*initialize the new array*/
    int i;
    /*copy the old array into the new array*/
    for(i = 0; i < v->size; i++) {
       largerArray->data[i] = v->data[i];
       largerArray->size++;
    }
freeDynArr(v); /*free memory of the old array*/
v = &largerArray; /*point to the new array*/
}
首先,对于for循环中的两条语句,我得到了错误消息invalid type参数'->'have struct DynArr。这是一个突然出现的新错误,尽管我没有对这个特定的函数进行更改,它最初也没有给我错误。其次,当这个函数返回到调用它的函数时,数组的大小和容量将返回到它们以前的值。我的声明v=&largerArray;似乎没有预期的效果,即将新数组的所有指针和值分配给v。下面提供了上下文的完整代码。如有任何关于解决这两个问题的建议,我们将不胜感激。提前谢谢

#include <assert.h>
#include <stdlib.h>
#include "dynArray.h"

struct DynArr
{
   TYPE *data;      /* pointer to the data array */
   int size;        /* Number of elements in the array */
   int capacity;    /* capacity ofthe array */
};


/* ************************************************************************
Dynamic Array Functions
 ************************************************************************ */

/* Initialize (including allocation of data array) dynamic array.

param:  v       pointer to the dynamic array
param:  cap     capacity of the dynamic array
pre:    v is not null
post:   internal data array can hold cap elements
post:   v->data is not null
*/
void initDynArr(DynArr *v, int capacity)
{
    assert(capacity > 0);
    assert(v!= 0);
    v->data = (TYPE *) malloc(sizeof(TYPE) * capacity);
    assert(v->data != 0);
    v->size = 0;
    v->capacity = capacity;
}

    /* Allocate and initialize dynamic array.

param:  cap     desired capacity for the dyn array
pre:    none
post:   none
ret:    a non-null pointer to a dynArr of cap capacity
        and 0 elements in it.
    */
DynArr* newDynArr(int cap)
{
    assert(cap > 0);
    DynArr *r = (DynArr *)malloc(sizeof( DynArr));
    assert(r != 0);
    initDynArr(r,cap);
    return r;
}

/* Deallocate data array in dynamic array.

param:  v       pointer to the dynamic array
pre:    none
post:   d.data points to null
post:   size and capacity are 0
post:   the memory used by v->data is freed
*/
void freeDynArr(DynArr *v)
{
   if(v->data != 0)
   {
       free(v->data);   /* free the space on the heap */
       v->data = 0;     /* make it point to null */
   }
   v->size = 0;
   v->capacity = 0;
}

/* Deallocate data array and the dynamic array ure.

param:  v       pointer to the dynamic array
pre:    none
post:   the memory used by v->data is freed
post:   the memory used by d is freed
*/
void deleteDynArr(DynArr *v)
{
    freeDynArr(v);
    free(v);
}

/* Resizes the underlying array to be the size cap

param:  v       pointer to the dynamic array
param:  cap     the new desired capacity
pre:    v is not null
post:   v has capacity newCap
*/
void _dynArrSetCapacity(DynArr *v, int newCap)
 {
    assert(v != NULL);
        struct DynArr largerArray; /*create a new dynamic array*/
    initDynArr(&largerArray, newCap); /*initialize the new array*/
    int i;
    /*copy the old array into the new array*/
    for(i = 0; i < v->size; i++) {
       largerArray->data[i] = v->data[i];
       largerArray->size++;
}

     freeDynArr(v); /*free memory of the old array*/
     v = &largerArray; /*point to the new array*/
}

/* Get the size of the dynamic array

param:  v       pointer to the dynamic array
pre:    v is not null
post:   none
ret:    the size of the dynamic array
*/
int sizeDynArr(DynArr *v)
{
    int i;
     v->size = 0;
     for (i = 0; i < v->capacity; i++) {
         if (!(EQ(v->data[i], NULL))) {
            v->size++;
    }
}
return v->size;
}

 /*     Adds an element to the end of the dynamic array

param:  v       pointer to the dynamic array
param:  val     the value to add to the end of the dynamic array
pre:    the dynArry is not null
post:   size increases by 1
post:   if reached capacity, capacity is doubled
post:   val is in the last utilized position in the array*/
void addDynArr(DynArr *v, TYPE val)
{
    /* Check to see if a resize is necessary */
    assert(v != NULL);

   if(v->size >= v->capacity) {
           _dynArrSetCapacity(v, 2 * v->capacity);
   }
   v->data[v->size] = val;
   printf("Added %d to Array to position %d\n", v->data[v->size], v->size);
   v->size++;
}

/*  Get an element from the dynamic array from a specified position

param:  v       pointer to the dynamic array
param:  pos     integer index to get the element from
pre:    v is not null
pre:    v is not empty
pre:    pos < size of the dyn array and >= 0
post:   no changes to the dyn Array
ret:    value stored at index pos
*/

TYPE getDynArr(DynArr *v, int pos)
{
   assert(pos < v->size && pos >= 0);
   return v->data[pos];
}

/*  Put an item into the dynamic array at the specified location,
overwriting the element that was there

param:  v       pointer to the dynamic array
param:  pos     the index to put the value into
param:  val     the value to insert
pre:    v is not null
pre:    v is not empty
pre:    pos >= 0 and pos < size of the array
post:   index pos contains new value, val
*/
void putDynArr(DynArr *v, int pos, TYPE val)
{
    assert(pos >= 0 && pos < v->size);

    v->data[pos] = val;
    v->size++;
}

/*  Swap two specified elements in the dynamic array

param:  v       pointer to the dynamic array
param:  i,j     the elements to be swapped
pre:    v is not null
pre:    v is not empty
pre:    i, j >= 0 and i,j < size of the dynamic array
post:   index i now holds the value at j and index j now holds the value at i
 */
void swapDynArr(DynArr *v, int i, int  j)
{
    int temp = 0;
    assert(i >= 0 && i < v->size);
    assert(j >= 0 && j < v->size);
    temp = v->data[i];
    v->data[i] = v->data[j];
    v->data[j] = temp;

}

/*  Remove the element at the specified location from the array,
shifts other elements back one to fill the gap

param:  v       pointer to the dynamic array
param:  idx     location of element to remove
pre:    v is not null
pre:    v is not empty
pre:    idx < size and idx >= 0
post:   the element at idx is removed
post:   the elements past idx are moved back one
*/
 void removeAtDynArr(DynArr *v, int idx)
{
    int i;
    assert(idx < v->size && idx >= 0);

        printf("%d is being removed from array\n", v->data[idx]);
    v->data[idx] = 0;
    for (i = idx; i < v->size; i++) {
        v->data[i] = v->data[i + 1];
    }

    v->size--;
    v->data[v->size+1] = NULL;
}



/* ************************************************************************
    Stack Interface Functions
************************************************************************ */

/*  Returns boolean (encoded in an int) demonstrating whether or not the
dynamic array stack has an item on it.

param:  v       pointer to the dynamic array
pre:    the dynArr is not null
post:   none
ret:    1 if empty, otherwise 0
*/
int isEmptyDynArr(DynArr *v)
{
   if(v->size == 0) return 1;
       return 0;
}

/*  Push an element onto the top of the stack

param:  v       pointer to the dynamic array
param:  val     the value to push onto the stack
pre:    v is not null
post:   size increases by 1
        if reached capacity, capacity is doubled
        val is on the top of the stack
*/
void pushDynArr(DynArr *v, TYPE val)
{
    addDynArr(v, val);
    printf("Pushed %d on Stack\n",val);
}

/*  Returns the element at the top of the stack

param:  v       pointer to the dynamic array
pre:    v is not null
pre:    v is not empty
post:   no changes to the stack
*/
TYPE topDynArr(DynArr *v)
{
    assert(sizeDynArr(v) != 0);
    return getDynArr(v, sizeDynArr(v) - 1);
}

/* Removes the element on top of the stack

param:  v       pointer to the dynamic array
pre:    v is not null
pre:    v is not empty
post:   size is decremented by 1
        the top has been removed
*/
void popDynArr(DynArr *v)
{
    assert(sizeDynArr(v) != 0);
    removeAtDynArr(v, sizeDynArr(v) - 1);
    v->size--;
}

/* ************************************************************************
Bag Interface Functions
 ************************************************************************ */

/*  Returns boolean (encoded as an int) demonstrating whether or not
the specified value is in the collection
true = 1
false = 0

param:  v       pointer to the dynamic array
param:  val     the value to look for in the bag
pre:    v is not null
pre:    v is not empty
post:   no changes to the bag
*/
int containsDynArr(DynArr *v, TYPE val)
{

int i;
    for (i = 0; i < v->size; i++) {
        if(EQ(v->data[i], val)) {
            return 1;
        }
     }
    return 0;
}

/*  Removes the first occurrence of the specified value from the collection
if it occurs

param:  v       pointer to the dynamic array
param:  val     the value to remove from the array
pre:    v is not null
pre:    v is not empty
post:   val has been removed
post:   size of the bag is reduced by 1
 */
 void removeDynArr(DynArr *v, TYPE val)
 {
    int i;
    for (i = 0; i < v->size; i++) {
            if (EQ(val, v->data[i])) {
                 removeAtDynArr(v, i);
                 return;
            }
    }
}

int main(int argc, char** argv){
    printf("Program: Dynamically-allocated Array\n");
    int cap = 10;
    int i;

DynArr *r;
r = newDynArr(cap);


    for (i = 0; i < cap; i++) {
        pushDynArr(r, i);
    }

    r->size = sizeDynArr(r);
    if(isEmptyDynArr(r) == 1) {
        printf("Array is empty\n");
    }

    else if(isEmptyDynArr(r) == 0) {
        printf("Array is not empty\n");
    }
    removeDynArr(r, 5);

    printf("Before adding to array, size is %d and capacity is %d\n", r->size, r->capacity);
    printf("The top of the array before push is %d\n", topDynArr(r));

    for (i = r->size; i < cap + 4; i++) {
       pushDynArr(r,i);
    }

    printf("After adding to array, size is %d and capacity is %d\n", r->size, r->capacity);
    printf("The top of the array after push is %d\n", topDynArr(r));

    printf("The top of the array before remove is %d\n", topDynArr(r));
    printf("Before removing from array, size is %d and capacity is %d\n", r->size, r->capacity);

    for (i = r->size; i < cap; i++) {
        pushDynArr(r,i);
    }

    printf("After removing from array, size is %d and capacity is %d\n", r->size, r->capacity);
    printf("The top of the array after remove is %d\n", topDynArr(r));

    if (containsDynArr(r, 3) == 1) {
        printf("Value 30 is in the array.\n");
    }

    printf("The top of the array before pop is %d\n", topDynArr(r));
    popDynArr(r);
    printf("The top of the array after pop is %d\n", topDynArr(r));

deleteDynArr(r);

   return 0;
}
struct DynArr largerArray是一个堆栈变量,它只存在于当前堆栈上。v=&largerArray使v指向堆栈上的内存地址。然后您的函数返回,堆栈被销毁,因此v指向不存在的内存,当其他函数回收此堆栈空间时,该内存将进一步被重写

您也从未真正创建过动态数组

DynArr *r;
initDynArr(r, cap);
r是一个指向DynArray的指针,这是它的类型,但是您没有初始化它以实际指向这样一个数组,initDynArr假设r已经指向DynArray,但事实并非如此,它是未初始化的。要么是正确的

DynArr r;
initDynArr(&r, cap);
在这种情况下,DynArray存在于堆栈或

DynArr *r = malloc(sizeof(*r));
initDynArr(r, cap);
在这种情况下,DynArray存在于堆上

在内存管理方面,您的代码有太多错误,我甚至不知道从哪里开始

也许你应该。这家伙已经实现了你想在这里实现的东西

struct DynArr largerArray是堆栈变量,它只存在于当前堆栈上。v=&largerArray使v指向堆栈上的内存地址。然后您的函数返回,堆栈被销毁,因此v指向不存在的内存,当其他函数回收此堆栈空间时,该内存将进一步被重写

您也从未真正创建过动态数组

DynArr *r;
initDynArr(r, cap);
r是一个指向DynArray的指针,这是它的类型,但是您没有初始化它以实际指向这样一个数组,initDynArr假设r已经指向DynArray,但事实并非如此,它是未初始化的。要么是正确的

DynArr r;
initDynArr(&r, cap);
在这种情况下,DynArray存在于堆栈或

DynArr *r = malloc(sizeof(*r));
initDynArr(r, cap);
在这种情况下,DynArray存在于堆上

在内存管理方面,您的代码有太多错误,我甚至不知道从哪里开始

也许你应该。这家伙已经实现了你想在这里实现的东西

在_dynArrSetCapacity中,您只需将本地指针v更改为指向本地堆栈变量,这不会影响v所指向的实际数据。你需要使用

*v = largerArray;
要从largerArray中复制。

在_dynArrSetCapacity中,您只需将本地指针v更改为指向本地堆栈变量,这不会影响v所指向的实际数据。你需要使用

*v = largerArray;
从largerArray复制。

忘记堆栈。largerArray是自动管理的。当_dynArrSetCapacity返回时,该对象将被销毁

当您传递给C中的函数时,您传递的是值。这意味着函数接收新对象中的数据副本,而不是旧对象中的数据副本。如果更改新对象,旧对象将保持不变。v=&largerArray;无效,因为v是副本,而不是原件。请注意,在下面的示例中,parse_by_value_示例中的int x与main中的int x不是同一个对象

数组[]下标运算符实际上是指针下标运算符;数组会衰减为指针,除非它们出现在诸如&array、sizeof array之类的表达式中或用于初始化

你在读哪本书?看来你有麻烦了。我有信心,如果你在遇到问题时做练习,不要跳过它们,你将从K&R 2E中获益。

忘掉这一堆。largerArray是自动管理的。当_dynArrSetCapacity返回时,该对象将被销毁

当您传递给C中的函数时,您传递的是值。这意味着函数接收新对象中的数据副本,而不是旧对象中的数据副本。如果更改新对象,旧对象将保持不变。v=&largerArray;无效,因为v是副本,而不是原件。请注意,在下面的示例中,parse_by_value_示例中的int x与main中的int x不是同一个对象

数组[]下标运算符实际上是指针下标运算符;数组衰减为指针,除非它们位于表达式中,如&array、sizeof array或 它们用于初始化


你在读哪本书?看来你有麻烦了。我相信,如果您在遇到问题时进行练习,不要跳过它们,您将从K&R 2E中获益。

这是大量代码。你能把范围缩小到问题吗?问题在从顶部开始的第五个功能中,即dynArraySetCapacity。我包含了上下文的代码。有些人喜欢这样。我编辑了原始帖子,并复制了在我描述的问题中导致问题的特定代码。我把代码放在我文章的底部作为背景。这是很多代码。你能把范围缩小到问题吗?问题在从顶部开始的第五个功能中,即dynArraySetCapacity。我包含了上下文的代码。有些人喜欢这样。我编辑了原始帖子,并复制了在我描述的问题中导致问题的特定代码。我将代码保存在context.Hmmm的帖子底部。我正在以与第一个数组相同的方式初始化和填充第二个数组,因此我错误地认为,构建一个新数组并将指针指向它是一件简单的事情。关于如何创建第二个数组以使其不在堆栈上,有什么建议吗?嗯。我正在以与第一个数组相同的方式初始化和填充第二个数组,因此我错误地假设这听起来像是构建一个新数组并将指针指向它的简单问题。关于如何创建第二个数组以使其不在堆栈上,有什么建议吗?Kernighan的C编程语言您正在做练习吗?由于时间限制,还没有。我想在数据结构课上自学C语言。我认为通过学习汇编语言,我在内存管理方面掌握得相当好,但C语言是一种负担。C不仅适用于x86,而且是标准化的。记住,有很多种组装形式。。。如果您编写符合标准的C,它在任何符合标准的C编译器可以针对的处理器上的行为都是相同的。学习C语言,就好像它是你从未见过的东西,而不是假设它与汇编语言有共同之处。做练习,因为它们是一种确保你理解内容的机制。Kernighan的C编程语言你在做练习吗?还没有,因为时间有限。我想在数据结构课上自学C语言。我认为通过学习汇编语言,我在内存管理方面掌握得相当好,但C语言是一种负担。C不仅适用于x86,而且是标准化的。记住,有很多种组装形式。。。如果您编写符合标准的C,它在任何符合标准的C编译器可以针对的处理器上的行为都是相同的。学习C语言,就好像它是你从未见过的东西,而不是假设它与汇编语言有共同之处。做练习,因为它们是确保你理解内容的一种机制。