我正在Fortran中编写一个新代码,并且在使用可分配数组或指针数组之间犹豫不决.我在某处读到可分配数组比指针数组有明显优势:
1)效率更高,因为它们在内存中总是连续的
2)没有内存泄漏是可能的
有人能证实吗?你建议使用哪一个?在这两种备选方案之间的代码执行速度方面有什么结果?
arrays fortran pointers memory-management dynamic-memory-allocation
在我的应用程序中,我必须从一组图像(MRC图像)加载volumedata并将像素数据保存在内存中.(图像是灰度级的,因此每像素一个字节).
我的开发环境是QT框架,MinGW for Windows和GCC for Linux.
目前,我使用一个简单的数据结构来存储volumedata:
unsigned char *volumeData;
Run Code Online (Sandbox Code Playgroud)
并按如下方式进行大量分配.
volumeData=new unsigned char[imageXsize * imageYsize * numofImages];
Run Code Online (Sandbox Code Playgroud)
以下是访问给定平面中图像数据的重要方法,例如
unsigned char* getXYPlaneSlice(int z_value);
unsigned char* getYZPlaneSlice(int x_value);
unsigned char* getZXPlaneSlice(int y_value);
Run Code Online (Sandbox Code Playgroud)
使用我简单的数据结构,很容易实现上述方法.
但是我们可能需要在未来采用体积大小为2000x2000x1000(~3.7Gb).而目前的数据结构将无法处理这些庞大的数据.
如何避免碎片?现在,即使使用1000x1000x200数据,应用程序也会崩溃,从而导致bad_alloc.什么是更改数据结构的最佳方法?我应该使用链接列表,每个块大小为100mb.
此外,用户应该能够在体积数据上执行一些图像处理过滤器,并且还应该能够重置为原始像素值.这意味着,我应该保留两份卷数据.与目前的实施类似.
unsigned char*volumeDataOriginal;
unsigned char*volumeDataCurrent;
因此,对于2000x2000x1000数据范围,它将使用大约8Gb(每个音量4Gb).但在Win32中,地址空间为4GB.如何解决这个问题?我应该使用64位应用程序?
编辑:这是我的应用程序的快照 
基本上,我加载了体积数据(来自MRC格式的图像集),并将它们显示在不同的平面查看器中(XY,YX,YZ.Image显示XY平面查看器).我需要保持在上面3种数据访问方法,用于显示特定平面中的图像.使用滑块栏用户可以更改要在所选平面中显示的图像)
提前致谢.
我怎么能对数组使用动态内存分配?
例如,下面是一个数组,其中我从.txt文件中读取单个单词并在数组中逐字保存:
码:
char words[1000][15];
Run Code Online (Sandbox Code Playgroud)
这里1000定义了数组可以保存的单词数,每个单词可以包含不超过15个字符.
现在我希望该程序应该为它计算的单词数量动态分配内存.例如,.txt文件可能包含大于1000的单词.现在我希望程序应该计算单词数并相应地分配内存.
由于我们不能使用变量代替[1000],因此我对如何实现逻辑完全空白.请帮助我这方面.
编程语言:C平台:ARM编译器:ADS 1.2
我需要跟踪melloc/free项目中的简单调用.我只需要了解程序分配了所有资源后需要多少堆内存的基本概念.因此,我为malloc/free调用提供了一个包装器.在这些包装器中,我需要在malloc调用时递增当前内存计数,并在free调用时递减它.这个malloc案例很简单,因为我有来自调用者的大小.我想知道如何处理这种free情况,因为我需要在某处存储指针/大小映射.这是C,我没有标准的地图来轻松实现这一点.
我试图避免在任何库中链接,所以更喜欢*.c/h实现.
所以我想知道是否已经有一个简单的实现可能会引导我.如果没有,这是继续实施的动机.
编辑:纯粹用于调试,此代码不随产品提供.
编辑:根据Makis的回答进行初步实施.我很感激对此的反馈.
编辑:重新实施
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <limits.h>
static size_t gnCurrentMemory = 0;
static size_t gnPeakMemory = 0;
void *MemAlloc (size_t nSize)
{
void *pMem = malloc(sizeof(size_t) + nSize);
if (pMem)
{
size_t *pSize = (size_t *)pMem;
memcpy(pSize, &nSize, sizeof(nSize));
gnCurrentMemory += nSize;
if (gnCurrentMemory > gnPeakMemory)
{
gnPeakMemory = gnCurrentMemory;
}
printf("PMemAlloc (%#X) - Size (%d), Current …Run Code Online (Sandbox Code Playgroud) 这是在C++中在堆上创建变量的方法:
T *ptr = new T;
Run Code Online (Sandbox Code Playgroud)
ptr显然是指向新T的指针.我的问题是,你能做到这一点:
T *ptr = new T*;
Run Code Online (Sandbox Code Playgroud)
这似乎可能导致一些非常非常危险的代码.有谁知道这是否可行/如何正确使用它?
当您使用指针在堆上分配动态内存时,
char *buffer_heap = new char[15];
Run Code Online (Sandbox Code Playgroud)
它将在内存中表示为:
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««þþþ
Run Code Online (Sandbox Code Playgroud)
为什么最后没有一个NULL终止字符而不是««««««««þþþ?
realloc 用于动态重新分配内存.
假设我已经使用该malloc函数分配了7个字节,现在我想将其扩展到30个字节.
如果内存中没有30个字节的连续(连续单行)空间,后台会发生什么?
是否有任何错误或内存将被分配?
#include <iostream>
using namespace std;
class base
{
int a;
public:
base() {a =0;}
};
class derv :public base
{
int b;
public:
derv() {b =1;}
};
int main()
{
base *pb = new derv();
delete pb;
}
Run Code Online (Sandbox Code Playgroud)
我在derv类中没有虚拟析构函数,它只删除了derv对象的基本部分吗?
c++ polymorphism dynamic-memory-allocation virtual-destructor
我知道手动动态内存分配通常是一个坏主意,但它有时比使用更好的解决方案,比方说,std::vector?
举一个粗略的例子,如果我必须存储一个n整数数组,其中n<= 16,比如说.我可以使用它来实现它
int* data = new int[n]; //assuming n is set beforehand
Run Code Online (Sandbox Code Playgroud)
或使用矢量:
std::vector<int> data;
Run Code Online (Sandbox Code Playgroud)
使用一个std::vector或者是否存在实际情况,手动分配动态内存是一个更好的想法,以提高效率,这绝对是一个更好的主意吗?
#include <stdlib.h>
void *operator new[](size_t size, int n){
if( size != 0 && n != 0 )
return calloc(n, size);
return calloc(1, 1);
}
int main(){
int * p1;
const int i = 0;
// p1 = new (20) int[i] ; // Case 1 (OK)
p1 = new (20) (int[i]); // Case 2 (Warning)
if( p1 == 0 )
return 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码(https://godbolt.org/g/hjo7Xn)与Clang 6.0.0成功编译,但是,GCC 7.3发出警告说在C++中禁止使用零长度数组.如果删除了括号(案例1),警告就会消失.
与静态分配的零长度数组(C++ 03:8.3.4/1)不同,允许动态分配的零长度数组(C++ 03:5.3.4/6).尽管如此,在C++标准中,只有在遵循new-expression的两个可能语法路径之一时,才明确允许后者,即具有new-type-id且没有括号的路径(Case 1).
是否允许C++标准在第二个语法路径后使用带有零长度数组的new-expression,即使用 …
c++ ×6
arrays ×3
c ×3
memory ×2
c++11 ×1
fortran ×1
heap-memory ×1
new-operator ×1
pointers ×1
polymorphism ×1
realloc ×1
stdvector ×1
visual-c++ ×1