gpt4 book ai didi

c++ - realloc 在调整数组大小的特定索引大小后抛出错误

转载 作者:行者123 更新时间:2023-11-30 03:14:22 25 4
gpt4 key购买 nike

所以我正在使用 realloc 和重复加倍制作一个调整大小的数组,我的数组工作正常,直到它的大小为 134217728,但是一旦我按下第 134217729 个元素,即我为 134217728*2 调用调整大小函数,realloc 返回 0。

我认为我的内存已满,但我有 8 Gbs 的 Ram,我在 Vs 代码上使用 Windows 10 MinGW 32 位编译器,如果我愿意,如何进一步增加我的数组的大小。这是 Windows 的问题还是我做错了什么?

#include<iostream>
#include<string.h>
#include <ctime>
using namespace std;
template<class X>
class ArrayStack{
X* a =(int*) malloc(1 * sizeof(int));;
int top=0;
int length=1;

void resize(int size){
cout<<"resizing to "<<size<<endl;
X* temp=(X*) realloc (a, size * sizeof(X));
if(temp==0){
cout<<"No continous memory left for the stack ";
}
length=size;
a=temp;
}

public:
void push(X item){
if(top==length){
resize(length*2);
}
a[top++]=item;
}

X pop(){
if(top<=length/4){
resize(length/2);
}
return a[--top];
}

bool IsEmpty(){
return top==0;
}
};

int main(){
ArrayStack <int> newStack;
for(unsigned long long int i=0;i<134217729 ;i++){
// In case of int the max size of array stack i can make is of length 134217728 using repeated doubling and realloc
int r = rand()%1000;
newStack.push(r);
}
while(!newStack.IsEmpty()){
newStack.pop();
}
}

realloc 返回 0。

最佳答案

由于这似乎与家庭作业相关,让我们从基础开始,您可以从中吸取教训并将其纳入您的重新分配方案。首先,如上所述,不要将 new/deletemalloc/calloc/realloc 混合使用。虽然它们执行类似的分配功能,但它们的实现完全不同。

也就是说,没有什么可以阻止您编写一个简短的重新分配函数(比如 reallocNew),它将使用 newdelete 来执行重新分配。由于上面您讨论了在重新分配时将当前分配的大小加倍,因此您只需创建一个 T 类型的新数组,其内存是当前内存的两倍。然后从旧数组复制到新数组(使用 memcpy),然后 delete[] 旧数组将新重新分配的 block 返回给调用者以分配给原始指针.

reallocNew 函数的一个简短示例,它采用指向原始内存块的指针以及指向当前元素数量的指针(将在函数内更新并提供给调用者虽然指针)可以如下所示:

template<class T>
T *reallocNew (const T *ptr, size_t *nelem)
{
/* make new allocated array with 2X the number of elements */
T *tmp = new T[2 * *nelem];

/* copy old elements to new block of mem */
std::memcpy (tmp, ptr, *nelem * sizeof *ptr);
delete[] ptr; /* delete the old block of memory */
*nelem *= 2; /* update the number of element counter */

return tmp; /* return pointer to reallocated block of memory */
}

一个使用重新分配函数的简短示例程序,最初从分配的 block 开始以保存 2-int 然后 reallocNew2, 4 & 8 元素存储添加到数组的 10-int 值。完整的例子可以是:

#include <iostream>
#include <cstring>

template<class T>
T *reallocNew (const T *ptr, size_t *nelem)
{
/* make new allocated array with 2X the number of elements */
T *tmp = new T[2 * *nelem];

/* copy old elements to new block of mem */
std::memcpy (tmp, ptr, *nelem * sizeof *ptr);
delete[] ptr; /* delete the old block of memory */
*nelem *= 2; /* update the number of element counter */

return tmp; /* return pointer to reallocated block of memory */
}

int main (void) {

size_t nelem = 2, /* no of elements alloced */
used = 0; /* no. of element counter */
int *arr = new int[nelem]; /* allocate initial elements */

for (; used < 10; used++) { /* loop adding to array */
if (used == nelem) /* is realloc needed? */
arr = reallocNew (arr, &nelem); /* call reallocNew function */
arr[used] = used + 1; /* add value to array */
}

for (size_t i = 0; i < used; i++) /* loop over stored values outputting */
std::cout << "arr[" << i << "] : " << arr[i] << '\n';

delete[] arr; /* don't forget to free what you allocated */
}

注意:上面的重新分配方案与您在任何地方找到的方案相同。你想避免为每次添加重新分配,所以你选择一些合理的方案,比如添加一些固定数量的元素,将当前乘以某个大于一的分数,或者提供合理权衡的常见方案是将当前分配加倍每次需要重新分配。这允许在仅进行 3 次重新分配的情况下添加上面的 10 个元素(您最多可以添加 16 个元素而无需再次重新分配)。

(虽然内存将在程序退出时被释放,但嵌套在代码中的已分配内存的 delete[] 将防止内存泄漏)

示例使用/输出

$ ./bin/newdelrealloc
arr[0] : 1
arr[1] : 2
arr[2] : 3
arr[3] : 4
arr[4] : 5
arr[5] : 6
arr[6] : 7
arr[7] : 8
arr[8] : 9
arr[9] : 10

内存使用/错误检查

在您编写的任何动态分配内存的代码中,您对分配的任何内存块负有 2 个责任:(1) 始终保留指向起始地址的指针内存块,因此,(2) 它可以在不再需要时被释放

您必须使用内存错误检查程序来确保您不会尝试访问内存或写入超出/超出您分配的 block 的边界,尝试读取或基于未初始化的值进行条件跳转,最后, 以确认您释放了所有已分配的内存。

对于 Linux valgrind 是正常的选择。每个平台都有类似的内存检查器。它们都易于使用,只需通过它运行您的程序即可。

$ valgrind ./bin/newdelrealloc
==32331== Memcheck, a memory error detector
==32331== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==32331== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==32331== Command: ./bin/newdelrealloc
==32331==
arr[0] : 1
arr[1] : 2
arr[2] : 3
arr[3] : 4
arr[4] : 5
arr[5] : 6
arr[6] : 7
arr[7] : 8
arr[8] : 9
arr[9] : 10
==32331==
==32331== HEAP SUMMARY:
==32331== in use at exit: 0 bytes in 0 blocks
==32331== total heap usage: 5 allocs, 5 frees, 72,824 bytes allocated
==32331==
==32331== All heap blocks were freed -- no leaks are possible
==32331==
==32331== For counts of detected and suppressed errors, rerun with: -v
==32331== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始终确认您已释放所有分配的内存并且没有内存错误。

检查一下,如果您有任何问题,请告诉我。

关于c++ - realloc 在调整数组大小的特定索引大小后抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57883344/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com