我有一个数组,我想在运行时增加它的大小。我通过使用循环为数组的元素赋值,当循环的索引达到数组的元素数时,我想增加数组的大小。
我做了什么,实际上是有效的;我可以为数组的元素赋值,我通常无法在不增加数组大小的情况下为其分配任何值。不好的一面是,它在程序运行并顺利完成后让我崩溃。这有什么不对?可能是我尝试为阵列分配的内存已经填满了吗?
int main()
{
int arr[3];
int num_of_elements = sizeof(arr)/sizeof(arr[0]); // This gives '3', I checked
for(i = 0; i < 10; i++)
{
if(i == num_of_elements)
{
num_of_elements = num_of_elements + 10;
realloc(arr, num_of_elements);
}
arr[i] = i+10;
printf("%d\n", arr[i]);
}
return 0;
}
答案 0 :(得分:5)
你正在调用未定义的行为。来自standard §7.22.3.5
void *realloc(void *ptr, size_t size);
如果ptr是空指针,则realloc函数的行为类似于
malloc
指定大小的函数。 否则,如果ptr
与a不匹配 指针先前由内存管理函数返回,或者如果是 通过调用free或realloc
函数释放空间, 行为未定义。如果新对象的内存不可用 已分配,旧对象未释放,其值为 不变。
通过内存管理功能 - 它意味着malloc
等。arr
不是动态分配的内存。因此将此传递给realloc
是未定义的行为 - 在您的情况下,行为会导致您在程序中崩溃。
如果你这样做会有用
int *arr = malloc(sizeof(int)*3);
if( arr == NULL){
perror("Malloc failed");
exit(EXIT_FAILURE);
}
...
int *p = realloc(arr,num_of_elements*sizeof(int));
^^^^^
if(p == NULL ){
perror("realloc failed");
exit(EXIT_FAILURE);
}
arr = p;
检查realloc
的使用方式。
外卖将是: -
realloc
,malloc
的返回值。 10*sizeof(int)
个内存。arr = realloc(arr,SIZE)
如果realloc
失败,您的内存会泄漏。realloc
p
到arr=p
之后才会realloc
?目前有两个原因
答案是当NULL
失败时,如果您将arr
分配给NULL
,它现在会返回realloc
,那么您可能会遇到失去的情况对先前分配的内存的唯一引用 - 导致内存泄漏。这就是为什么我们这样做的原因。
请注意标准
may
函数返回指向新对象的指针( 可能 与指向旧对象的指针具有相同的值),或一个空指针 如果无法分配新对象。
请注意arr
部分 - 它可能与DataTemplate
指向的地址相同,或者可能不同。这解释了为什么我们应该将它存储在一些临时指针中,然后我们稍后再分配它。
答案 1 :(得分:1)
你应该这样做:
arr = realloc(arr, num_of_elements);
^^^^^
realloc()
不一定扩展或缩小已分配的内存就地,它使第一个参数指向的动态内存无效并分配新内存,同时保留内存以前的记忆。
一种可能的实现方式是:
void* realloc(void* ptr, size_t size) {
void* ret = malloc(size);
if (ret == NULL) return ret;
if (ptr != NULL) {
memcpy(ret, ptr, /* previous size from system */);
free(ptr);
}
return ret;
}