C 在结构中重新分配数组
我正在为学校写一个程序,要求我们创建一个结构,它有一个整数数组,还有两个整数变量,容量和大小,可以跟踪数组的大小和容量。当我需要为数组重新分配空间时,问题就开始了(教授不希望我们使用C 在结构中重新分配数组,c,arrays,struct,C,Arrays,Struct,我正在为学校写一个程序,要求我们创建一个结构,它有一个整数数组,还有两个整数变量,容量和大小,可以跟踪数组的大小和容量。当我需要为数组重新分配空间时,问题就开始了(教授不希望我们使用realloc)。这是代码 dynamicArray.h文件 dynamicArray.c文件 在v->data[v->size]=val时;线路。我确实注意到,当我在前面提到的代码行之前检查v->size的值时,它会返回垃圾值。这让我想到,当我将v传递到\u dynArrSetCapacity函数时,它是通过值传递
realloc
)。这是代码
dynamicArray.h文件
dynamicArray.c文件
在v->data[v->size]=val时;线路。我确实注意到,当我在前面提到的代码行之前检查v->size的值时,它会返回垃圾值。这让我想到,当我将v传递到
\u dynArrSetCapacity
函数时,它是通过值传递的,而不是通过引用传递的,但我不知道这是怎么可能的。非常感谢您的帮助。问题出在void\u dynArrSetCapacity(DynArr*v,int newCap)
。您可能需要检查所有涉及内存重新分配的函数是否存在类似问题
从技术上讲,C中没有引用,所以每个参数都是按值传递或复制的。但是您复制的是指针,而不是整个DynArray
对象。这意味着当您执行deleteDynArray()
时,内存会像您预期的那样消失,但是当您到达v=tmp
,它更改本地v
(本地副本)的值,而不是传入的v
。然后回到v->data[v->size]=val代码>,您可能正在访问尚未分配的内存,从而导致该错误
最快的修复方法(虽然我不是最好的)是对任何进行释放的函数使用双指针而不是单指针,如下所示:
void _dynArrSetCapacity(DynArr **v, int newCap)
{
DynArr *tmp = newDynArr(newCap);
/*copy contents of v to new array*/
......
/*delete contents of old array*/
deleteDynArr(*v);
/*assign address of new array to v*/
*v = tmp;
(*v)->size = newCap;
}
还有一种选择,我认为可能更好。您不必重新分配整个对象。仅包含所有相关对象的DynArray
对象中的内存块:TYPE*data
void _dynArrSetCapacity(DynArr *v, int newCap)
{
TYPE *tmp = (TYPE*)malloc(sizeof(Type) * newCap);
/*copy contents of v to new array*/
for (int i = 0; i < v->size; ++i)
tmp[i] = v->data[i];
/*delete contents of old array*/
free(v->data);
/*assign address of new array to v*/
v->data = tmp;
v->size = newCap;
}
void\u dynArrSetCapacity(DynArr*v,int newCap)
{
型号*tmp=(型号*)malloc(型号*sizeof)newCap;
/*将v的内容复制到新数组*/
对于(int i=0;isize;++i)
tmp[i]=v->data[i];
/*删除旧数组的内容*/
免费(v->数据);
/*将新数组的地址分配给v*/
v->data=tmp;
v->size=newCap;
}
问题出在void\u dynArrSetCapacity(DynArr*v,int newCap)
。您可能需要检查所有涉及内存重新分配的函数是否存在类似问题
从技术上讲,C中没有引用,所以每个参数都是按值传递或复制的。但是您复制的是指针,而不是整个DynArray
对象。这意味着当您执行deleteDynArray()
时,内存会像您预期的那样消失,但是当您到达v=tmp
,它更改本地v
(本地副本)的值,而不是传入的v
。然后回到v->data[v->size]=val代码>,您可能正在访问尚未分配的内存,从而导致该错误
最快的修复方法(虽然我不是最好的)是对任何进行释放的函数使用双指针而不是单指针,如下所示:
void _dynArrSetCapacity(DynArr **v, int newCap)
{
DynArr *tmp = newDynArr(newCap);
/*copy contents of v to new array*/
......
/*delete contents of old array*/
deleteDynArr(*v);
/*assign address of new array to v*/
*v = tmp;
(*v)->size = newCap;
}
还有一种选择,我认为可能更好。您不必重新分配整个对象。仅包含所有相关对象的DynArray
对象中的内存块:TYPE*data
void _dynArrSetCapacity(DynArr *v, int newCap)
{
TYPE *tmp = (TYPE*)malloc(sizeof(Type) * newCap);
/*copy contents of v to new array*/
for (int i = 0; i < v->size; ++i)
tmp[i] = v->data[i];
/*delete contents of old array*/
free(v->data);
/*assign address of new array to v*/
v->data = tmp;
v->size = newCap;
}
void\u dynArrSetCapacity(DynArr*v,int newCap)
{
型号*tmp=(型号*)malloc(型号*sizeof)newCap;
/*将v的内容复制到新数组*/
对于(int i=0;isize;++i)
tmp[i]=v->data[i];
/*删除旧数组的内容*/
免费(v->数据);
/*将新数组的地址分配给v*/
v->data=tmp;
v->size=newCap;
}
v=tmp\u dynArrSetCapacity
中的code>不会更改传入的调用方的v
。您正在更改一个局部变量。建议您使用该未使用的函数返回值从函数返回tmp
,并将其分配给调用者中的v
。请注意,以下划线开头的名称基本上保留供实现(编译器和库)使用。整个故事更加微妙,但差距不大。您的\u dynArrSetCapacity
函数似乎未在源文件之外使用-它应该是静态的
,并且不应该以下划线开头。v=tmp\u dynArrSetCapacity
中的code>不会更改传入的调用方的v
。您正在更改一个局部变量。建议您使用该未使用的函数返回值从函数返回tmp
,并将其分配给调用者中的v
。请注意,以下划线开头的名称基本上保留供实现(编译器和库)使用。整个故事更加微妙,但差距不大。您的\u dynArrSetCapacity
函数似乎未在源文件之外使用-它应该是静态的
,并且不应该以下划线.Wow开头。我离开我的电脑一会儿,然后回来找到大量的答案和信息。谢谢你的回复。Alex Yan您关于分配数组而不是整个结构的第二个建议非常有效,@JonathanLeffler对其进行了最后润色。谢谢哇!我离开我的电脑一会儿,然后回来找到大量的答案和信息。谢谢你的回复。Alex Yan您关于分配数组而不是整个结构的第二个建议非常有效,@JonathanLeffler对其进行了最后润色。谢谢
void _dynArrSetCapacity(DynArr **v, int newCap)
{
DynArr *tmp = newDynArr(newCap);
/*copy contents of v to new array*/
......
/*delete contents of old array*/
deleteDynArr(*v);
/*assign address of new array to v*/
*v = tmp;
(*v)->size = newCap;
}
void _dynArrSetCapacity(DynArr *v, int newCap)
{
TYPE *tmp = (TYPE*)malloc(sizeof(Type) * newCap);
/*copy contents of v to new array*/
for (int i = 0; i < v->size; ++i)
tmp[i] = v->data[i];
/*delete contents of old array*/
free(v->data);
/*assign address of new array to v*/
v->data = tmp;
v->size = newCap;
}