2016-03-06 55 views
-4

的动态矢量I具有用于动态矢量下面的结构:C结构

typedef struct { 
    TElement *data; 
    int len; 
}Vector; 

和2层的功能,一个初始化矢量,而另一个附加的元素:

Vector *initVector() 
{ 
    Vector *v; 
    v = malloc(sizeof(TElement)); 
    v->len = 0; 
    return v; 
} 
void append(Vector *v, TElement element) 
{ 
    v = (Vector *)realloc(v, (v->len + 1) * sizeof(TElement)); 
    v->data[v->len++] = element; 
} 

当我尝试追加一个元素时,程序崩溃,我不知道为什么,有什么想法?

+0

当您尝试调试时发现了什么? –

+2

'v = malloc(sizeof(TElement))'....腥...... –

+1

为什么'sizeof(TElement)'?这没有任何意义。 – juanchopanza

回答

0
  • 在功能initVector(),分配sizeof(Vector)代替sizeof(TElement)
  • 在功能append,修改v->data代替v和删除不需要的和有害铸造。

纠正代码:

Vector *initVector() 
{ 
    Vector *v; 
    v = malloc(sizeof(*v)); 
    v->len = 0; 
    return v; 
} 
void append(Vector *v, TElement element) 
{ 
    v->data = realloc(v->data, (v->len + 1) * sizeof(TElement)); 
    v->data[v->len++] = element; 
} 
1

在你的代码,vVector *型的,而你分配内存的TElement大小,这是错误的。

变化

v = malloc(sizeof(TElement)); 

v = malloc(sizeof*v); 

这就是说,

  • 务必检查的malloc()通过检查对NULL返回的指针,以避免任何可能的UB的成功,如果malloc()失败。

  • p = realloc(p,...)风格非常糟糕,因为,如果realloc()失败,您最终也会丢失实际的指针。在临时指针中捕获realloc()的返回值,针对NULL检查成功,然后返回原始指针。

0

在你的initvector中,你应该预留一个空间Vector。此外,你的必须设置v->dataNULL,或有效的分配指针,否则你的代码将有未定义的行为。

Vector *initVector() { 
    Vector *v; 
    v = malloc(sizeof Vector); 
    if (! v) { 
     /* error: malloc failed */ 
    } 
    v->data = 0; 
    v->len = 0; 
    return v; 
} 

append你应该要调整的区域指向data,而不是Vector分配本身:

void append(Vector *v, TElement element) { 
    TElement *new_p = realloc(v->data, (v->len + 1) * sizeof(TElement)); 

    if (!new_p) { 
     /* error: malloc failed */ 
    } 
    v->data = new_p; 
    v->data[v->len++] = element; 
} 

这也是一个很不错的主意,检查的malloc返回值;如果没有其他的话,在打印出合理的信息之后放弃在那里是有道理的,而不是用难以理解的SIGSEGV崩溃。


此外,生长所述向量中的一个项的时间意味着该项目的插入将与n物品的容器上O(n)的时间复杂度。最好以几何级数分配空间(例如,当您需要调整分配大小时,然后将分配扩大1.5倍或2倍,而不是一个常数),并从一些较大的最小分配8开始,或者16个项目。

0

你需要的是最后一个函数的以下

Vector *initVector() 
{ 
    Vector *v = malloc(sizeof(Vector)); 
           ^^^^^^ 
    if (v != NULL) 
    { 
     v->len = 0; 
     v->data = NULL; 
     ^^^^^^^^^^^^^^^ 
    } 

    return v; 
} 

void append(Vector *v, TElement element) 
{ 
    TElement *tmp = realloc(v->data, (v->len + 1) * sizeof(TElement)); 
          ^^^^^^^^  
    if (tmp != NULL) 
    { 
     v->data = tmp; 
     v->data[len++] = element; 
    } 
} 

返回类型可以从void改为int报告的新元素是被追加。例如

int append(Vector *v, TElement element) 
{ 
    int success; 

    TElement *tmp = realloc(v->data, (v->len + 1) * sizeof(TElement)); 
          ^^^^^^^^  
    if ((success = tmp != NULL)) 
    { 
     v->data = tmp; 
     v->data[len++] = element; 
    } 

    return success; 
}