如何在应用程序开始时分配所有内存,然后在整个过程中相应地进行类型转换

Posted

技术标签:

【中文标题】如何在应用程序开始时分配所有内存,然后在整个过程中相应地进行类型转换【英文标题】:How to allocate all memory at beginning of app and then typecast it accordingly throughout 【发布时间】:2013-12-12 01:30:36 【问题描述】:

我需要预先分配我的应用程序将使用的所有内存。然后在需要时用我需要进行计算的数据覆盖该内存。在进行任何计算之前,必须首先分配内存,因为我正在尝试并行运行多线程 CUDA 算法,正如我在此处的问题 (Multi-Threaded CPU CUDA application not asynchronous when calling CudaFree) 中所解释的那样。

我认为我可以将所需的所有内存分配为字节指针,然后将该指针存储为 void 指针:

void * allocateMemory()

    byte *mem;
    int nbytes = 13107200;
    mem = (byte *) malloc(nbytes);
    return mem;

稍后在我的程序中,我想使用已分配的内存来存储数据。我不提前知道数据的类型,但我知道它的大小不会超过分配的限制。

void doSomething(void * mem)

    int *a = (int*) mem;
    for (int i = 0; i < 100; i++)
    
        a[i] = i;
    

    //do stuff


还有许多其他函数,例如上面的 doSomething(void * mem),但它们使用 double 类型或 float 类型,甚至可能使用 byte 类型。我需要能够用我需要的任何数据类型覆盖最初分配的内存。上面的代码不起作用,因为它说我不能尊重 void 指针。它还说我试图读取或写入受保护的内存。

这样做的正确方法是什么?实现我的目标的最佳方法是在开始时分配所有内存,然后在整个过程中以必要的方式使用?谢谢!

【问题讨论】:

你正在尝试实现一个固定大小的堆。用碎片等解决这个问题并不容易。最好的办法是使用一个池,也许使用已经有这个的 boost。 刚刚看到你的另一个问题,我认为你误解了答案。他说的是做 malloc, loop, free, not begin loop, malloc, free, end loop。 我过去做过类似的事情,其中​​对象或多或少地永久分配在连续的存储区域中。如果您不需要解除分配/重用,则相当容易。如果您希望能够解除分配/重用,那么您正在实现自己的堆(为此我推荐使用笛卡尔树)。 (不过,至少,您需要维护一个“下一个”指针来分配下一个字节,并且可能还需要一个“最大”指针/长度来告诉您何时分配破坏了你的分配。) 你在上面展示的可能不是最干净、最聪明的方法,但它应该可以工作。我怀疑你的问题出在其他地方。 【参考方案1】:

听起来你有两个问题。

    无法取消引用 void 指针。在您的代码中的某处,您使用了来自allocateMemory() 的结果而没有进行强制转换。您提供的代码是可以的,但是编译器标记为错误的任何行都不行。例如,也许你有:

    void *foo = allocateMemory();
    foo[42];  // compiler doesn't have a real type here - error
    ((int*)foo)[42];  // compiler happy
    

    试图访问受保护的内存。在您的代码中的某处,您有一个无效的指针。最可能的原因是 allocateMemory() 返回 NULL(您没有检查它)。

您的一般方法对我来说似乎没问题;您描述的问题与代码中的细节有关,而不是整体想法。

【讨论】:

哇,我觉得自己很笨。大声笑我梳理了我的代码,发现这是一个复制粘贴错误。我将 ptr1、ptr2、ptr3 和 ptr4 设置为 allocateMemory()。我不小心做了两次ptr2,所以ptr3从来没有分配过内存。我猜这在尝试使用 ptr3 时会导致访问受保护的内存问题。我不确定为什么我有取消引用空指针问题,但是在修复了先前的错误并在这里和那里清理我的代码之后,我不再有任何错误。谢谢!

以上是关于如何在应用程序开始时分配所有内存,然后在整个过程中相应地进行类型转换的主要内容,如果未能解决你的问题,请参考以下文章

芹菜节拍进程在启动时分配大量内存

如何防止 Tensorflow 在使用 Eager Execution 时分配全部 GPU 内存?

如何实现内存堆

如何在运行时分配多维数组?

创建一个 MiniDump,不包括运行时分配的内存范围

linux 在启动时获得专用的缓冲