C++ realloc在调整数组大小时,在特定索引大小后抛出错误
因此,我正在使用realloc制作一个调整大小的数组,并重复加倍,我的数组工作良好,直到其大小为134217728,但只要我按下134217729元素,即我调用134217728*2的resize函数,realloc就会返回0 我想我的内存已经满了,但是我有8GBS的Ram,我正在Vs代码上使用Windows10MingW32位编译器。如果我想,如何进一步增加数组的大小。 这是Windows的问题还是做了什么错误C++ realloc在调整数组大小时,在特定索引大小后抛出错误,c++,pointers,memory-management,new-operator,realloc,C++,Pointers,Memory Management,New Operator,Realloc,因此,我正在使用realloc制作一个调整大小的数组,并重复加倍,我的数组工作良好,直到其大小为134217728,但只要我按下134217729元素,即我调用134217728*2的resize函数,realloc就会返回0 我想我的内存已经满了,但是我有8GBS的Ram,我正在Vs代码上使用Windows10MingW32位编译器。如果我想,如何进一步增加数组的大小。 这是Windows的问题还是做了什么错误 #include<iostream> #include<stri
#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();
}
}
#包括
#包括
#包括
使用名称空间std;
模板
类阵列堆栈{
X*a=(int*)malloc(1*sizeof(int));;
int-top=0;
整数长度=1;
空心调整大小(整数大小){
cout我只是根据上面的建议将代码更改为realloc/malloc/calloc等与新的和模板化的类混合在一起,但它仍然存在这个错误。
我仍然在猜测,我没有足够的空间,正如上面的人所建议的,谢谢大家支持我,这真的很难从Python和JS到C++的语言来,还有一些小问题引起了很多问题,谢谢你们耐心地解释,我在课堂上问了这个问题,谢谢你们。时间,如果你有任何其他方法可以绕过它短到使用矢量请建议
这是一个类似于vector的赋值,我只是想在上面写一个包装器,用它获取所有的数组片段,用一个超类/数组/散列链接它们,然后根据请求所需的索引和子数组中的哪个来分配传入的请求特定索引
#include<iostream>
#include<string.h>
#include <ctime>
using namespace std;
template<class X>
class ArrayStack{
X* a =new X[1];
unsigned long long int top=0;
unsigned long long int length=1;
void resize(unsigned long long int size){
X* temp=new X[size];
length=size;
for(unsigned long long int i=0;i<size/2;i++){
temp[i]=a[i];
}
delete []a;
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<134217728 ;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();
}
}
#包括
#包括
#包括
使用名称空间std;
模板
类阵列堆栈{
X*a=新的X[1];
无符号长整型top=0;
无符号长整型长度=1;
无效调整大小(无符号长整型大小){
X*温度=新X[尺寸];
长度=尺寸;
对于(unsigned long long int i=0;i既然这看起来与家庭作业相关,那么让我们从基础开始,您可以从中吸取教训,并将它们合并到您的重新分配方案中。首先,如上所述,不要将new/delete
与malloc/calloc/realloc
混合使用。虽然它们执行类似的分配函数,但它们的实现是e我相信这是不一样的
也就是说,没有什么可以阻止您编写一个简短的重新分配函数(比如reallocNew
)这将使用new
和delete
执行重新分配。由于上面讨论了在重新分配时将当前分配的大小增加一倍,您只需创建一个T
类型的新数组,该数组的当前内存增加一倍。然后,您可以从旧数组复制到新数组(使用memcpy
)然后delete[]
将新重新分配的块返回给调用者,以分配给原始指针
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 */
}
注意:重新分配方案与您在任何地方找到的方案相同。您希望避免每次添加都重新分配,因此您选择一些合理的方案,例如添加一些固定数量的元素,将当前值乘以大于1的某个分数,或者提供合理折衷的常见方案是将e每次需要重新分配时的当前分配。这允许在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
内存使用/错误检查
在您编写的任何动态分配内存的代码中,对于所分配的任何内存块,您有两个责任:(1)始终保留指向内存块起始地址的指针,以便(2)在不再需要它时可以释放它
必须使用内存错误检查程序,以确保您不会试图访问内存或写入超出/超出分配的块的边界,尝试在未初始化的值上读取或建立条件跳转,最后确认释放所有已分配的内存
对于Linuxvalgrind
是正常的选择。每个平台都有类似的内存检查器。它们都很容易使用,只需运行程序即可
$ 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)
始终确认已释放所有已分配的内存,并且没有内存错误
如果您有任何疑问,请仔细查看并告诉我。32位程序的最大地址空间为4 GB。根据环境的不同,允许的实际地址空间可能是其中的一半。这还包括程序代码、静态数据、库、堆栈等
调整分配大小(始终使用delete
/new
,通常也使用realloc
)需要在删除旧分配之前创建新分配
请考虑前一个和新分配的总字节大小(元素计数次数SIZE),是否接近或超过2 GB?
如果确实如此,则说明应用程序的可用内存不足
两种解决方案:以较小的块处理数据(不容易、不有趣、性能差),或切换到64位编译器(这样做)
有一个64位版本的MinGW可用。不要realloc
你拥有的new
ed。realloc
只能与malloc
家族的其他成员一起使用。对于new
,没有任何东西可以与realloc
相比,主要是因为
$ 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)