Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 堆中的DLL内存泄漏_C#_C++_Opencv_Dll - Fatal编程技术网

C# 堆中的DLL内存泄漏

C# 堆中的DLL内存泄漏,c#,c++,opencv,dll,C#,C++,Opencv,Dll,我正在调试某人的代码,但出现了一个错误:这可能是由于堆损坏,这表明.exe或它加载的任何DLL中存在错误。我研究并了解到这是由于一些内存泄漏,对象没有从堆中正确删除。我看了又看代码(逐行调试),它在return语句中崩溃了。下面是代码:问题出在哪里 首先是调用DLL的c代码 public class Analysis { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1),

我正在调试某人的代码,但出现了一个错误:这可能是由于堆损坏,这表明.exe或它加载的任何DLL中存在错误。我研究并了解到这是由于一些内存泄漏,对象没有从堆中正确删除。我看了又看代码(逐行调试),它在return语句中崩溃了。下面是代码:问题出在哪里

首先是调用DLL的c代码

    public class Analysis
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1), Serializable]
        public struct Pothole
        {
            public int Id;
            public int FrameNumber;
            public int LeftX;
            public int TopY;
            public int Width;
            public int Height;
            public int Certainty; // note that this is a percentage value, hence integer
            public double Latitude;
            public double Longitude;
            public double Speed;
            public double Area;
            public double Volume;
            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string TimeCreated;
            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 200)]
            public string CroppedImage;
            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 200)]
            public string LeftImage;
            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 200)]
            public string RightImage;
        };

        private int progress;
        public int Progress
        {
            get { return progress; }
            set { progress = value; }
        }

        public List<FileInfo> AllVideoFiles;
        public List<FileInfo> FramesInDir;
        public List<GpsPoint> GpsList;
        public VideoMetaData MetaData;
        public List<TrackPothole> PotholeList;
        public VideoHandling VideoHandler;

        public int verbose; //if verbose, then you get a lot of wordy output on what the program is doing

        private VspDatabaseEntities1 _vde;        

        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate void ProgressCallback(int value);
        public event ProgressCallback OnProgressUpdated;

        //initializes video files and calibraiton file names
        [DllImport(@"Analyser.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern int Initialize(string SettingsDir, int SettingDirLength, string LeftVideoFile, int LeftFileLength, 
            string RightVideoFile, int RightFileLength, string GpsCoordsFile, int GpsFileLength, string OutputDirectory, int OutputDirLength);

        //analyse road files (do everything)
        [DllImport(@"Analyser.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public static extern int Start([MarshalAs(UnmanagedType.FunctionPtr)] ProgressCallback callbackPointer, int verbose);

        //Does the analysis of videos, uses the c++ analysis Start() function
        public void Go(ProgressBar bar)
        {
            //flag -> should actually be set outside of function, can't find the outside
            verbose = 1;            

            //obtain parameters from settings.settings
            string inputDir = Properties.Settings.Default["InputDir"].ToString();
            string outputDir = Properties.Settings.Default["OutputDir"].ToString();
            string settingsDir = Properties.Settings.Default["SettingsDir"].ToString();

            //setup directories and filenames            
            //string camfile = settingsDir + "\\" + "Calib.yaml"; => now we send the directory, not the specific file
            string rightvid = "";
            string leftvid = "";
            string gpsfile = "";

            //Associate multiple files according to creation times and loop through matching pairs 
            //(this works because of the copy operation? -> but won't everything have the same time then?)
            AllVideoFiles = GetFiles(inputDir, "*.avi");            
            List<FileInfo> rightvids = new List<FileInfo>(AllVideoFiles.Where(v => v.FullName.Contains("3D_R")).OrderBy(v => v.CreationTime));
            List<FileInfo> leftvids = new List<FileInfo>(AllVideoFiles.Where(v => v.FullName.Contains("3D_L")).OrderBy(v => v.CreationTime));
            List<FileInfo> gpsfiles = new List<FileInfo>(GetFiles(inputDir, "*.txt").OrderBy(g => g.CreationTime));
            Console.WriteLine("Got this far1");
            //Check that the number of right and left video files and gps files match
            int lowestCount = 0;
            if (rightvids.Count != leftvids.Count)
            {
                MessageBox.Show("Error: The number of right camera videos does not match the number of left camera videos!");
                if (rightvids.Count < leftvids.Count)
                    lowestCount = rightvids.Count;
                else
                    lowestCount = leftvids.Count;
            }
            else
                lowestCount = rightvids.Count;

            if (gpsfiles.Count != lowestCount)
            {
                MessageBox.Show("Error: The number of gps data files does not match the number of right camera video files!");
                if (gpsfiles.Count < lowestCount)
                    lowestCount = gpsfiles.Count;
            }

            //@todo 
            //Currently, looping through the files and hoping there is only one in the file.
            Console.WriteLine("Got this far2");
            for (int i = 0; i < lowestCount; i++)
            {
                rightvid = rightvids[i].FullName;
                leftvid = leftvids[i].FullName;
                gpsfile = gpsfiles[i].FullName;

                if (verbose==1)
                    Console.WriteLine("C# FileNames: " + settingsDir + " " + outputDir + " " + leftvid + " " + gpsfile);

                //Pass the filenames to the c++ functions
                int InitReturn = Initialize(settingsDir, settingsDir.Length, leftvid, leftvid.Length,
                    rightvid, rightvid.Length, gpsfile, gpsfile.Length, outputDir, outputDir.Length);

                if (verbose == 1)
                {
                    Console.WriteLine("Initilize return value : " + InitReturn);
                    Report();
                }

                //Setup the progress bar
                ProgressCallback callback = (value) => bar.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                    new Action(delegate() {bar.Value = value;} ));

                //***RUN THE ANALYSIS
                Console.WriteLine("Got this far4");
                int start_ret_val = Start(callback, verbose);
                if (verbose==1) Console.WriteLine("Start return value: " + start_ret_val);

                //Create the pothole array
                Pothole[] potArr = new Pothole[10000];
                Thread.Sleep(1000); //@todo Why sleep?

                if (start_ret_val > 0)
                {
                    //fill up the array 
                    ///@todo How does this impact the memory wastage?
                    potArr = GetPotholes(start_ret_val);

                    MessageBox.Show("Analysis completed");

                    //bar.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                      //                  new Action( delegate() { bar.Value = 0; } ));
                }
                else
                {
                    MessageBox.Show("Analysis returned with error code : " + start_ret_val); //@todo Add some interpretation here
                }

                Console.WriteLine("Got this far5");
            }                
        }
公共类分析
{
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi,Pack=1),可序列化]
公共结构坑洞
{
公共int Id;
公共整数帧号;
公共int-LeftX;
公共关系;
公共整数宽度;
公众内部高度;
public int确定性;//注意这是一个百分比值,因此是整数
公共双纬度;
公共双经度;
公共双速;
公共双区;
公共双卷;
[MarshalAsAttribute(UnmanagedType.ByValTStr,SizeConst=20)]
创建公共字符串;
[MarshalAsAttribute(UnmanagedType.ByValTStr,SizeConst=200)]
公共字符串裁剪图像;
[MarshalAsAttribute(UnmanagedType.ByValTStr,SizeConst=200)]
公共字符串左图;
[MarshalAsAttribute(UnmanagedType.ByValTStr,SizeConst=200)]
公众形象;
};
私人投资进展;
公共信息技术进步
{
获取{返回进度;}
设置{progress=value;}
}
公开列出所有视频文件;
公开名单框架;
公开名单;
公共视频元数据;
公开名单洞穴学家;
公共视频处理器;
public int verbose;//如果是verbose,那么您会得到很多关于程序正在做什么的冗长输出
私有VspDatabaseEntities1 _vde;
[非托管函数指针(CallingConvention.StdCall)]
公共委托无效进程回调(int值);
公共事件进度回调;进度更新;
//初始化视频文件和calibraiton文件名
[DllImport(@“Analyser.dll”,CallingConvention=CallingConvention.Cdecl,CharSet=CharSet.Unicode)]
public static extern int Initialize(字符串setingsdir、int setingdirlength、字符串LeftVideoFile、int LeftFileLength、,
string RightVideoFile、int RightFileLength、string GpsCoordsFile、int GpsFileLength、string OutputDirectory、int OutputDirLength);
//分析道路文件(执行所有操作)
[DllImport(@“Analyser.dll”,CallingConvention=CallingConvention.Cdecl,CharSet=CharSet.Ansi)]
公共静态外部int Start([Marshallas(UnmanagedType.FunctionPtr)]ProgressCallback回调回调指针,int verbose);
//分析视频,使用C++分析开始()函数
公共作废Go(进度条)
{
//flag->实际上应该设置在函数外部,找不到外部
详细=1;
//从settings.settings获取参数
字符串inputDir=Properties.Settings.Default[“inputDir”].ToString();
字符串outputDir=Properties.Settings.Default[“outputDir”].ToString();
string settingsDir=Properties.Settings.Default[“settingsDir”].ToString();
//设置目录和文件名
//字符串camfile=settingsDir+“\\”+“Calib.yaml”;=>现在我们发送的是目录,而不是特定的文件
字符串rightvid=“”;
字符串leftvid=“”;
字符串gpsfile=“”;
//根据创建时间关联多个文件并通过匹配对循环
//(这是因为复制操作?->但是不是所有的东西都有相同的时间吗?)
AllVideoFiles=GetFiles(inputDir,“*.avi”);
List rightvids=新列表(AllVideoFiles.Where(v=>v.FullName.Contains(“3D_R”)).OrderBy(v=>v.CreationTime));
List leftvids=新列表(AllVideoFiles.Where(v=>v.FullName.Contains(“3D_L”)).OrderBy(v=>v.CreationTime));
List gpsfiles=新列表(GetFiles(inputDir,*.txt”).OrderBy(g=>g.CreationTime));
Console.WriteLine(“搞定这件事了”);
//检查左右视频文件和gps文件的数量是否匹配
int lowestCount=0;
if(rightvids.Count!=leftvids.Count)
{
MessageBox.Show(“错误:右摄像头视频的数量与左摄像头视频的数量不匹配!”);
if(rightvids.Countcv::Mat RunClassifier(cv::Mat& frame, cv::Mat& mask, std::vector<CvANN_MLP*>& anns, std::vector<int>& criteria,std::vector<float>& thresholds, Mat& final_certainty)
{
    //instantiate certainty matrix
    std::vector<Mat> indiv_certs;
    for (unsigned int i = 0; i < anns.size(); i++)
        indiv_certs.push_back(Mat::zeros(frame.size(), CV_32FC1) );
    Mat certainty = Mat::zeros(frame.size(), CV_32FC1);
    final_certainty = Mat::zeros(frame.size(), CV_32FC1);

    Mat final_image = frame.clone();
    Mat* individual_masks = new Mat[anns.size()]();
    for (unsigned int iter = 0; iter < anns.size();iter++)
    {
        individual_masks[iter] = Mat::zeros(frame.rows,frame.cols,CV_32F);
    }
    Mat final_mask = Mat::zeros(frame.rows,frame.cols,CV_32F);

    //Convert the image to HSV colorspace (You could probably save a bit more if you converted and normalised the frame to 32F beforehand
    // and not individually for each channel.
    Mat hsv;
    std::vector<Mat> hsv_channels;
    cvtColor(frame, hsv, CV_BGR2HSV);
    split(hsv, hsv_channels);

    Mat hue, value, saturation;
    hsv_channels.at(HUE).convertTo(hue, CV_32F);
    hue /= HUE_MAX;
    hue = 1- hue;   
    hsv_channels.at(SATURATION).convertTo(saturation, CV_32F);
    Mat sat_pure = saturation.clone();
    saturation /= SATURATION_MAX;
    hsv_channels.at(VALUE).convertTo(value, CV_32F);
    value /= VALUE_MAX;

    //loop through the anns 
    //Declare multithreading variables
    PCERT_DATA pCert_Array[3];
    DWORD dwThreadIdArray[3];
    HANDLE hThreadArray[3];

    for (unsigned int ann_iter = 0; ann_iter < anns.size(); ann_iter++)
    {
        //allocate memory for thread data
        pCert_Array[ann_iter] = (PCERT_DATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CERT_DATA) );

        bool fft_flag = FALSE;
        //Convert the image block according to the ann
        switch (criteria.at(ann_iter))
        {
            case HUE:
            {
                pCert_Array[ann_iter]->converted_frame = &hue;
                break;
            }
            case SATURATION:
            {
                pCert_Array[ann_iter]->converted_frame = &saturation;
                break;
            }
            case VALUE:
            {
                pCert_Array[ann_iter]->converted_frame = &value;;
                break;
            }
            case FREQUENCY:
            {
                pCert_Array[ann_iter]->converted_frame = &sat_pure;
                fft_flag = TRUE;
                break;
            }
            default:
            {
                return Mat();
            }
        }


        //assign data to memory
        pCert_Array[ann_iter]->ann = anns.at(ann_iter);
        pCert_Array[ann_iter]->certainty = &(indiv_certs[ann_iter]);

        pCert_Array[ann_iter]->mask = &mask;
        pCert_Array[ann_iter]->fft_flag = fft_flag;
        pCert_Array[ann_iter]->individual_mask =  &(individual_masks[ann_iter]);
        pCert_Array[ann_iter]->threshold = thresholds.at(ann_iter);

        //call CalculateCertainty
        hThreadArray[ann_iter] = CreateThread( 
            NULL,                   // default security attributes
            0,                      // use default stack size  
            ComputeCertainty,       // thread function name
            pCert_Array[ann_iter],          // argument to thread function 
            0,                      // use default creation flags 
            &dwThreadIdArray[ann_iter]);   // returns the thread identifier         
    }

    //wait for all the threads to stop computing
    WaitForMultipleObjects(anns.size(), hThreadArray, TRUE, INFINITE);

    //summing operation of certanties
    for (unsigned int i = 0; i < anns.size(); i++)
        certainty += indiv_certs[i];

    //AND all the various ANN outputs
    Mat temp = Mat::zeros(individual_masks[0].size(), individual_masks[0].type() );
    for (unsigned int i = 0; i < anns.size(); i++)
        temp += individual_masks[i];

    Mat temp_binary_mask = (temp == anns.size());
    temp = Mat::ones(individual_masks[0].size(), individual_masks[0].type() );
    temp.copyTo(final_mask, temp_binary_mask);

    cv::multiply(final_mask, certainty, final_certainty, 1.0/anns.size() );

    delete individual_masks;

    //deallocate threading memory used
    for(unsigned int i=0; i<anns.size(); i++)
    {
        CloseHandle(hThreadArray[i]);
        if(pCert_Array[i] != NULL)
        {
            HeapFree(GetProcessHeap(), 0, pCert_Array[i]);
            pCert_Array[i] = NULL;    // Ensure address is not reused.
        }
    }

    return final_mask;
}
for (unsigned int ann_iter = 0; ann_iter < anns.size(); ann_iter++) 
{ 
    //allocate memory for thread data 
    pCert_Array[ann_iter] = (PCERT_DATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CERT_DATA) );