ç调整动态数组 [英] C resizing a dynamic array

查看:161
本文介绍了ç调整动态数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创造了一个C类动态数组。我最有实现的一切,现在我测试出来。目前它得到一个调整大小时卡住。我用的printf的遵循问题。它看起来像大小调整工作,但是当我去加我的下一个项目后调整大小,它停止在那里。

我想这可能与我的内存分配,否则我指点和调整大小时释放阵列的方式做。我是新的C所以这些都是我的症结所在。

 的#include<&ASSERT.H GT;
#包括LT&;&stdlib.h中GT;
#包括dynArray.h
#包括LT&;&stdio.h中GT;结构DynArr
{
    TYPE *数据; / *指针数据阵列* /
    INT大小; / *数组中元素的数量* /
    INT能力; / *阵列的容量* /
};
/ * ************ ************************
    动态数组功能
************************************************** ********************** * // *初始化(包括数据数组分配)动态数组。    参数:v指针动态数组
    参数:动态数组的容量上限
    pre:v不是空
    岗位:内部数据数组可以容纳帽元素
    岗位:V->数据不空
* /
无效initDynArr(DynArr * V,INT容量)
{
    断言(容量大于0);
    断言(ⅴ!= 0);
    V->数据=(TYPE *)malloc的(的sizeof(TYPE)*容量);
    断言(V->数据!= 0);
    V->大小= 0;
    V->容量=能力;
}/ *分配和初始化动态数组。    参数:盖所需的容量为达因阵列
    pre:无
    发帖:无
    RET:一个非空指针的上限容量dynArr
            并在它0的元素。
* /
DynArr * newDynArr(INT帽)
{
    断言(帽大于0);
    DynArr * R =(DynArr *)malloc的(的sizeof(DynArr));
    断言(R = 0!);
    initDynArr(R,帽);
    返回ř;
}/ *动态数组解除分配数据数组。    参数:v指针动态数组
    pre:无
    岗位:d.data点为null
    岗位:尺寸和容量为0
    岗位:由V-&GT所使用的内存;数据被释放
* /
无效freeDynArr(DynArr * V)
{
    如果(V->!数据= 0)
    {
        免费(V->数据); / *释放堆空间* /
        V->数据= 0; / *使其指向空* /
    }
    V->大小= 0;
    V->能力= 0;
}/ *解除分配数据阵列和动态数组URE。    参数:v指针动态数组
    pre:无
    岗位:由V-&GT所使用的内存;数据被释放
    后:用d使用的内存被释放
* /
无效deleteDynArr(DynArr * V)
{
    freeDynArr(五);
    免费(V);
}/ *的大小调整底层数组是尺寸帽    参数:v指针动态数组
    参数:盖新的期望容量
    pre:v不是空
    岗位:V有能力newCap
* /
无效_dynArrSetCapacity(DynArr * V,诠释newCap)
{
    DynArr * newArr = newDynArr(newCap); //创建新帽新数组
    INT X;
    为(X = 0; X&下; sizeDynArr(五); X ++){
        addDynArr(newArr,V->数据[X]); //复制数据
    }
    freeDynArr(五); //自由旧v
    V->容量= newCap;
    V->大小= newArr->大小;
    V = newArr; //点​​v到新阵列
}/ *获取动态数组的大小    参数:v指针动态数组
    pre:v不是空
    发帖:无
    RET:动态数组的大小
* /
INT sizeDynArr(DynArr * V)
{
    返回V->大小;
}/ *添加一个元素的动态数组的末尾    参数:v指针动态数组
    参数:val要添加到动态数组的末尾
    pre:在dynArry不为空
    岗位:1尺寸的增大
    后:如果达产,产能翻倍
    岗位:VAL是在数组中最后使用的位置
* /
无效addDynArr(DynArr * V,TYPE VAL)
{
    / *检查,看是否有大小调整是必要的* /
    的printf(大小数:%d \\ TCAP数:%d \\ n,V>的大小,V>能力);
    如果(V->大小> = V->能力){
        的printf(在调整大小..);
        _dynArrSetCapacity(V,2 * V->能力);
    }
    V->数据[V->大小= VAL; //调整大小后,这种情况不会发生。
    V->大小++;
}/ *从指定位置获取从动态数组中的元素    参数:v指针动态数组
    参数:POS整数索引来从元素
    pre:v不是空
    pre:v不是空
    pre:POS&L​​T;在DYN阵列和大于大小= 0
    发帖:无更改DYN阵列
    RET:值存储在索引POS
* /TYPE getDynArr(DynArr * V,INT POS)
{
    / *在指定位置返回数据元素阵列内* /    断言(正&下; sizeDynArr(ⅴ)及&放大器; POS&GT = 0); //值是零和大小之间
    返回V->数据[POS]在位置//返回deferenced int值
}/ *在指定的位置从数组中删除元素,
    变化等元素退一填补了国内空白    参数:v指针动态数组
    参数:元素的IDX位置删除
    pre:v不是空
    pre:v不是空
    pre:IDX<尺寸和IDX> = 0
    岗位:在IDX的元素被删除
    后:元素过去IDX移动退一万
* /
无效removeAtDynArr(DynArr * V,INT IDX)
{
    INT I;
    断言(IDX&下; sizeDynArr(ⅴ)及&放大器; idx的&GT = 0);    对于(i = IDX; I< sizeDynArr(五)-1;我++){
        v [I]。数据= V [I + 1]。数据;
    }
    V-> size--;
}/ * ************ ************************
    栈接口函数
************************************************** ********************** * // *返回布尔(带一个int codeD)证实是否将
    动态数组叠层具有在其上的项目。    参数:v指针动态数组
    pre:在dynArr不为空
    发帖:无
    RET:1如果为空,否则为0
* /
INT isEmptyDynArr(DynArr * V)
{
    返回(sizeDynArr(ⅴ)== 0);
}/ *推的元件到堆栈的顶部    参数:v指针动态数组
    参数:以法尔推入堆栈中的价值
    pre:v不是空
    岗位:1尺寸的增大
            如果达产,产能翻倍
            val为在堆栈的顶部
* /
无效pushDynArr(DynArr * V,TYPE VAL)
{
    addDynArr(ⅴ,VAL);
}/ *返回元件在堆栈的顶部    参数:v指针动态数组
    pre:v不是空
    pre:v不是空
    发帖:无更改堆栈
* /
TYPE topDynArr(DynArr * V)
{
    返回getDynArr(ⅴ,sizeDynArr(ⅴ)-1);
}/ *删除堆栈顶部的元素    参数:v指针动态数组
    pre:v不是空
    pre:v不是空
    岗位:大小减1
            顶部已除去
* /
无效popDynArr(DynArr * V)
{
    removeAtDynArr(ⅴ,sizeDynArr(ⅴ)-1);
}
INT主(INT ARGC,CHAR *的argv []){
    DynArr * MYD = newDynArr(5);
    INT X;    addDynArr(MYD,1);
    addDynArr(MYD,2);
    //的printf(顶数:%d,sizeDynArr(MYD));
    //输出(大小数:%d \\ Ttop的数:%d \\ n,sizeDynArr(MYD),topDynArr(MYD));    为(X = 0; X&下; = 5; X ++){
        addDynArr(MYD,X);
        //输出(大小数:%d \\ Ttop的数:%d \\ n,sizeDynArr(MYD),topDynArr(MYD));
        pushDynArr(MYD,X * 2);
        //输出(大小数:%d \\ Ttop的数:%d \\ n,sizeDynArr(MYD),topDynArr(MYD));
    }
    的printf(HI);    deleteDynArr(MYD);    返回0;
}


解决方案

您函数 _dynArrSetCapacity 不工作打算,问题是出在下面几行:

  V->容量= newCap;
    V->大小= newArr->大小;
    V = newArr; //点​​v到新阵列
}

最后的指令基本没用​​。 v 是一个指针。更改不会影响 _dynArrSetCapacity 之外的实际使用指针。因此, V->数据 0 addDynArr 和你会得到一个分段错误:

  _dynArrSetCapacity(V,2 * V->能力);
}
V->数据[V->大小= VAL; //调整大小后,这种情况不会发生。

或者使用 V->数据= newArr-方式>数据或指针使用指针代替

I'm creating a dynamic array data structure for a C class. I have most everything implemented and now I'm testing it out. It's currently getting stuck during a resize. I've used printf's to follow the issue. It looks like the resize is working, but when I go to add my next item post resize, it's stopping there.

I think it may have to do with my memory allocation or the way I'm pointing and freeing arrays during the resize. I'm new to C so these are my sticking points.

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

struct DynArr
{
    TYPE *data;     /* pointer to the data array */
    int size;       /* Number of elements in the array */
    int capacity;   /* capacity of the 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)
{   
    DynArr* newArr = newDynArr(newCap);     //Create new array with new cap
    int x;
    for(x = 0; x < sizeDynArr(v); x++){
        addDynArr(newArr, v->data[x]);      //copy data
    }
    freeDynArr(v);                  //free old v
    v->capacity = newCap;
    v->size = newArr->size;
    v = newArr;                 //point v to 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)
{
    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 */
    printf("size: %d\tcap: %d\n", v->size, v->capacity);
    if(v->size >= v->capacity) {
        printf("in resize..");
        _dynArrSetCapacity(v, 2 * v->capacity);
    }
    v->data[v->size] = val;         //after a resize this doesn't happen.
    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)
{
    /*returns data element at specified position within the array*/

    assert(pos < sizeDynArr(v) && pos >= 0);        //value is between zero and size
    return v->data[pos];                            //returns deferenced int value at position
}

/*  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 < sizeDynArr(v) && idx >= 0);

    for (i = idx; i < sizeDynArr(v)-1; i++){
        v[i].data = v[i+1].data;
    }
    v->size--;
}



/* ************************************************************************
    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)
{
    return (sizeDynArr(v) == 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);
}

/*  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)
{
    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)
{
    removeAtDynArr(v, sizeDynArr(v)-1);
}


int main(int argc, char* argv[]){
    DynArr* myD = newDynArr(5);
    int x;

    addDynArr(myD, 1);
    addDynArr(myD, 2);
    //printf("top: %d", sizeDynArr(myD));
    //printf("size: %d\ttop: %d\n", sizeDynArr(myD), topDynArr(myD));

    for(x = 0; x <= 5; x++){
        addDynArr(myD, x);
        //printf("size: %d\ttop: %d\n", sizeDynArr(myD), topDynArr(myD));
        pushDynArr(myD, x * 2);
        //printf("size: %d\ttop: %d\n", sizeDynArr(myD), topDynArr(myD));
    }


    printf("HI");

    deleteDynArr(myD);

    return 0;   
}

解决方案

Your function _dynArrSetCapacity doesn't work as intended, the problem is in the following lines:

    v->capacity = newCap;
    v->size = newArr->size;
    v = newArr;                 //point v to new array
}

The last instruction is basically useless. v is a pointer. Changes won't affect the actual used pointer outside of _dynArrSetCapacity. Thus v->data is 0 in addDynArr and you'll get a segmentation fault:

    _dynArrSetCapacity(v, 2 * v->capacity);
}
v->data[v->size] = val;         //after a resize this doesn't happen.

Either use v->data = newArr->data or use a pointer on a pointer instead.

这篇关于ç调整动态数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆