【问题标题】:stl map, set error: memory clobbered past end of allocated blockstl 映射,设置错误:内存在分配块结束后被破坏
【发布时间】:2011-10-07 07:51:55
【问题描述】:

当我试图解决这个面试问题时:在一个等于目标数的数组中找到连续元素的总和,所以我想出了以下代码。但是,我真的不明白为什么它有一些内存分配问题。这是完整代码的link。当我尝试将 currSum 的第二个元素插入到集合和映射中时,它会出现一些错误消息,例如“内存在分配块结束后被破坏”。是不是set,map为insert动态分配的?我真的不明白为什么它不像我想的那样工作。

我也把完整的代码贴在这里:

        #include <map>
        #include <set>
        #include <iostream>
        using namespace std;

        void print_array(int arr[], int start, int end)
        {
            for(int i=start;i<=end;i++)
                cout<<arr[i]<<" ";
            cout<<endl;
        }

        //given an array, find the continous sum of the array which is a target number
        void findTargetSum(int arr[], int target, int sizeArr)
        {
            map<int, int> valIdxMap;
            set<int> prevSet;
            int* currSum= new int(sizeArr+1);
            currSum[0]=0;   
            for(int i=1;i<=sizeArr;i++)
            {
                currSum[i]=currSum[i-1]+arr[i-1];
            }

            //now the problem is to find two elements i, j in array currSum,where currSum[j]-currSum[i]=target && j>i
            for(int i=0; i<=sizeArr;i++)
            {
                int tmp=currSum[i]-target;
                set<int>::iterator iter=prevSet.find(tmp);
                if (iter !=prevSet.end())
                {
                    cout<<"located one range of array elements with sum to"<<target<<endl;
                    int startIdx=valIdxMap[*iter];
                    print_array(arr,startIdx,i-1);
                }
                else
                {
                    prevSet.insert(currSum[i]);
                    valIdxMap.insert(make_pair(currSum[i],i));
                }
            }
            delete currSum;
        }

        void testfindTargetSum()
        {
            int tst_arr[]={2,4,5,-1,3,8};
            int target=11;
            findTargetSum(tst_arr,11,6);
        }

        int main()
        {
           testfindTargetSum();
           return 1;
        }

【问题讨论】:

    标签: c++ memory-management map set


    【解决方案1】:

    错误在这一行:

    int* currSum= new int(sizeArr+1);
    

    该行获取单个int 并将其初始化为值sizeArr+1。您可能的意思是:

    int* currSum= new int[sizeArr+1];
    

    这将获取int 类型的sizeArr+1 元素块。此外,您必须将行 delete currSum; 更改为 delete [] currSum;

    另一方面,我的建议是不要手动管理内存,而是使用标准容器,例如:

    std::vector<int> currSum( sizeArr+1 );
    

    基本上将是您当前实现的就地替代品,它会自动管理内存。

    在实现时,我相信您实际上可以通过在迭代时累积三个变量中的开始索引、结束索引和值的总和,在 O(N) 中无需任何额外内存就可以做到这一点。当累计值小于目标值时,增加结束索引并添加该值。当累计值增长到高于目标值时,增加起始索引并按该量减少累计值。

    【讨论】:

    • :) 抱歉我犯了这个愚蠢的错误。而且我认为您的算法可能效果更好,我会尽快实现它
    • 我没有仔细阅读你的算法,我认为两个指针(startIdx,endIdx)在这里不起作用。因为我没有说所有数组元素都是正数。例如:array[12,2,-3,-4],目标数为9。即使开始的累加和已经是12(startIdx=endIdx=0),仍然需要增加endIdx。我说的对吗?
    • @user268451:你是对的,该算法只有在所有数字都是非负数时才有效。我的下一个选择是一个二维数组,其中每个位置 (i,j) 包含元素 [i..j] 的总和(只有一半的矩阵将被初始化)。如果矩阵中的任何元素都达到了目标,坐标将为您提供范围。
    【解决方案2】:

    你写的

    int* currSum= new int(sizeArr+1);
    

    你可能是说

    int* currSum= new int[sizeArr+1];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-07
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多