我有一个动态矢量的结构:
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 :(得分:1)
在您的代码中,v
的类型为Vector *
,并且您正在分配大小为TElement
的内存,这是错误的。
更改
v = malloc(sizeof(TElement));
到
v = malloc(sizeof*v);
那就是说,
在malloc()
失败的情况下,通过检查返回的指针是否为NULL来检查malloc()
是否成功,以避免任何可能的UB。
p = realloc(p,...)
样式非常糟糕,因为如果realloc()
失败,你也会失去实际的指针。在临时指针中捕获realloc()
的返回值,检查NULL是否成功,然后分配回原始指针。
答案 1 :(得分: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;
}
答案 2 :(得分:0)
在你的initVector中,你应该为一个Vector
预留空间。此外,必须将v->data
设置为NULL
,或者设置有效的分配指针,否则您的代码将具有未定义的行为。
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项。
答案 3 :(得分: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;
}