- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我正在使用 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/delete
与 malloc/calloc/realloc
混合使用。虽然它们执行类似的分配功能,但它们的实现完全不同。
也就是说,没有什么可以阻止您编写一个简短的重新分配函数(比如 reallocNew
),它将使用 new
和 delete
来执行重新分配。由于上面您讨论了在重新分配时将当前分配的大小加倍,因此您只需创建一个 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
然后 reallocNew
在 2, 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/
如果 realloc 失败并返回 NULL 是前一个缓冲区被释放还是保持不变?我没有在手册页中找到那条特定的信息,我不确定该怎么做。如果内存被释放,那么双重释放可能会有风险。如果没有,就会发生泄漏。
OS: Linux CC: GCC 4.8.2 目标:改变 char* 的大小 -> 变小 问题:更改后的大小相同... 行是带有数据的字符串... 代码片段: char * tmp = NUL
在一个函数中我使用了 malloc : void name1(struct stos* s) { s = malloc (4 * sizeof (int)); } 一切正常。但是后来我用了rea
我知道有一个 realloc允许我调整内存块大小的函数(它与一个免费函数配对)。但是,我正在尝试对一些成员指针使用 new 而不是 realloc 分配内存的 c++ 类执行相同的操作。在 C++ 中
我正在尝试在 C 中创建一个动态整数数组,它应该在填满后自动将其大小加倍。 要扩展数组的大小,我想使用 realloc 函数。不幸的是,指向我的 DynamicArray 和 GCC 崩溃的数据的指针
这是我被教导使用的方式 realloc() : int *a = malloc(10); a = realloc(a, 100); // Why do we do "a = .... ?" if(a
我尝试在每个循环中使用 realloc(),因此我只为 C 中的 int 数组使用必要的内存,但输出值已更改。尽管如此,在我的代码中使用 Valgrind 时,我得到了正确的值。 我在做 Advent
平台:Linux 3.2.0 x86 (Debian Wheezy) 编译器:GCC 4.7.2 (Debian 4.7.2-5) 我想知道如果我尝试 realloc() 一个已递增的指针会发生什么。
我知道可以在内核中使用 malloc 在 GPU 的全局内存上分配内存。是否也可以使用realloc? 最佳答案 您可以为您的数据类型编写自己的 realloc 设备函数。 只需为新数组分配新空间,将
我在对数组使用 malloc/realloc 命令时遇到了一些问题。我创建了一个包含一些整数的小数组,并尝试通过使用 realloc 扩展大小并添加值来为其添加一个值,但是当我这样做时,0 索引的值不
背景: 我使用 calloc() 创建了一个数组,一切都运行良好。然后我使用 realloc() 使数组更大。它似乎只是创建一个没有任何内容的新指针,并在我尝试访问数组中的元素时调用运行时错误。 我的
假设我已经使用 malloc() 分配了内存,如果我在我的代码中这样做: char *newline = realloc ( oldline , newsize ); // Assuming oldl
我正在尝试在下面的程序中使用 realloc 重新分配内存,并在我使用 malloc(i = (int*)malloc(5 * sizeof(int))) 使用react的 realloc 初始内存之
为什么下面的代码输出两次 4,而不是 8 和 20?谢谢 int size = 0; int *pointer; pointer = malloc(2 * sizeof(int)); size = s
我正在尝试将一堆 WCHAR 添加到缓冲区。这个函数就是将它添加到我的缓冲区中的原因.. DWORD add_to_buffer(BYTE *databuffer, WCHAR *path, WCHA
可能我的大脑现在不能正常工作......我想知道为什么我在我的代码中收到提到的错误: int ** zm; zm = (int**)calloc(1, sizeof(int*)); *zm = (in
我正在尝试用 C 语言编写代码,但遇到了 realloc 的问题。该代码在某个时间点工作正常,但在另一时间重新分配期间因堆损坏错误而崩溃。我已将填充数据的结构和函数粘贴到其中。谁能告诉我我是否在这里做
realloc 会改变它的第一个参数吗? 改变第一个参数是否取决于实现? 有什么理由不应该是const吗?作为反例,memcpy 将其 src 参数设为 const。 ISO C 标准,第 7.20.
我在 realloc 中遇到此错误,该错误仅发生在我学校的实验室计算机上,而不发生在我的计算机上。 在此程序中,我将行号存储在 File_Node 结构中。 File_Node 是一个链表的一部分,每
来自 man realloc:realloc() 函数返回一个指向新分配的内存的指针,该指针适合任何类型的变量,可能与 ptr 不同,如果请求失败,则返回 NULL . 因此在此代码片段中: ptr
我是一名优秀的程序员,十分优秀!