Ctypes方法中的内存泄漏

时间:2015-01-25 18:17:59

标签: python c memory-leaks ctypes

我有一个主要用Python编写的项目。这个项目在我的Raspberry Pi(模型B)上运行。使用Pi Camera我记录到一个流。每秒我都会暂停录制以从流中获取最后一帧并将其与较旧的帧进行比较。比较是在C代码中完成的(主要是因为它比Python快)。

使用Ctypes从Python调用C代码。请参阅下面的代码。

# Load picturecomparer.so and set argument and return types
cmethod = ctypes.CDLL(Paths.CMODULE_LOCATION)
cmethod.compare_pictures.restype = ctypes.c_double
cmethod.compare_pictures.argtypes = [ctypes.c_char_p, types.c_char_p]

必须比较的2张图像存储在磁盘上。 Python将两个图像的路径作为C代码的参数。 C代码将返回一个值(double),这是两个图像的百分比差异。

# Call the C method to compare the images
difflevel = cmethod.compare_pictures(path1, path2)

C代码如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#ifndef STB_IMAGE_IMPLEMENTATION
    #define STB_IMAGE_IMPLEMENTATION
    #include "stb_image.h"

    #ifndef STBI_ASSERT
        #define STBI_ASSERT(x)
    #endif
#endif

#define COLOR_R 0
#define COLOR_G 1
#define COLOR_B 2
#define OFFSET 10

double compare_pictures(const char* path1, const char* path2);

double compare_pictures(const char* path1, const char* path2)
{
    double totalDiff = 0.0, value;
    unsigned int x, y;

    int width1, height1, comps1;
    unsigned char * image1 = stbi_load(path1, &width1, &height1, &comps1, 0);

    int width2, height2, comps2;
    unsigned char * image2 = stbi_load(path2, &width2, &height2, &comps2, 0);

    // Perform some checks to be sure images are valid
    if (image1 == NULL | image2 == NULL) { return 0; }
    if (width1 != width2 | height1 != height2) { return 0; }

    for (y = 0; y < height1; y++)
    {
        for (x = 0; x < width1; x++)
        {
            // Calculate difference in RED 
            value = (int)image1[(x + y*width1) * comps1 + COLOR_R] - (int)image2[(x + y*width2) * comps2 + COLOR_R];
            if (value < OFFSET && value > (OFFSET * -1)) { value = 0; }
            totalDiff += fabs(value) / 255.0;

            // Calculate difference in GREEN 
            value = (int)image1[(x + y*width1) * comps1 + COLOR_G] - (int)image2[(x + y*width2) * comps2 + COLOR_G];
            if (value < OFFSET && value >(OFFSET * -1)) { value = 0; }
            totalDiff += fabs(value) / 255.0;

            // Calculate difference in BLUE
            value = (int)image1[(x + y*width1) * comps1 + COLOR_B] - (int)image2[(x + y*width2) * comps2 + COLOR_B];
            if (value < OFFSET && value >(OFFSET * -1)) { value = 0; }
            totalDiff += fabs(value) / 255.0;
        }
    }
    totalDiff = 100.0 * totalDiff / (double)(width1 * height1 * 3);
    return totalDiff;
}

C代码每隔约2秒执行一次。我刚注意到内存泄漏。大约10到15分钟后,我的Raspberry Pi就像还剩10MB柱塞一样。几分钟后它崩溃了,不再响应了。

我已经做了一些检查,以找出导致我项目的原因。如果我禁用C代码,我的整个项目使用大约30-40MB RAM。这个项目是我所有的Raspberry Pi必须执行的。

模型B:512MB ram,在CPU和GPU之间共享。 GPU:128MB(/boot/config.txt)。 我的Linux发行版使用:~60MB。

所以我的项目有300MB左右。

希望有人可以指出我哪里出错了,或者我必须自己打电话给GC等等。

提前致谢。

P.S。我知道图像比较并不是最好的方法,但它现在适用于我。

1 个答案:

答案 0 :(得分:2)

由于图像被返回,因为指向缓冲区stbi_load的指针必须为它们分配空间,并且在返回之前不会释放此空间,因此内存泄漏并不令人惊讶。

检查文档以查看是否存在特定的stpi_free函数,或尝试在最终返回之前添加free(image1); free(image2);

检查后我可以断然说你应该在回来之前致电STBI_FREE(image1); STBI_FREE(image2);