C++ munmap_chunk() - 无效指针错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22817288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:14:05  来源:igfitidea点击:

munmap_chunk() - Invalid pointer error

c++memorymemory-managementsdlglm-math

提问by Actimia

I'm writing a renderer using low-level SDL functions to learn how it all works. I am now trying to do polygon drawing, but I run into errors possibly due to my inexperience with C++. When running the code I get a munmap_chunk() - Invalid pointererror. Searching reveals that it is most likely due to free()-ing the memory twice. The error happens when returning from the function. I realize that the error comes from automatically free()ing memory which has been automatically free()d before, but I'm not experienced enough with C++ to spot the error. Any clues?

我正在使用低级 SDL 函数编写渲染器来了解它是如何工作的。我现在正在尝试绘制多边形,但由于我对 C++ 缺乏经验,我遇到了错误。运行代码时出现munmap_chunk() - Invalid pointer错误。搜索表明这很可能是由于 free() 两次内存。从函数返回时发生错误。我意识到错误来自之前free()已经自动free()d 的自动ing 内存,但我对 C++ 的经验不足,无法发现错误。有什么线索吗?

My code:

我的代码:

void DrawPolygon (const vector<vec3> & verts, vec3 color){

    // 0. Project to the screen
    vector<ivec2> vertices(verts.size());
    for(int i = 0; i < verts.size(); i++){
        VertexShader(verts.at(i), vertices.at(i));
    }

    // 1. Find max and min y-value of the polygon 
    // and compute the number of rows it occupies.
    int miny = vertices[0].y;
    int maxy = vertices[0].y;

    for (int i = 1; i < 3; i++){
        if (vertices[i].y < miny){
            miny = vertices[i].y;
        }
        if (vertices[i].y > maxy){
            maxy = vertices[i].y;
        }
    }

    int rows = abs(maxy - miny) + 1;
    // 2. Resize leftPixels and rightPixels 
    // so that they have an element for each row. 

    vector<ivec2> leftPixels(rows);
    vector<ivec2> rightPixels(rows);

    // 3. Initialize the x-coordinates in leftPixels 
    // to some really large value and the x-coordinates 
    // in rightPixels to some really small value. 

    for(int i = 0; i < rows; i++){
        leftPixels[i].x = std::numeric_limits<int>::max();
        rightPixels[i].x = std::numeric_limits<int>::min();
        leftPixels[i].y = miny + i;
        rightPixels[i].y = miny + i;
    }

    // 4. Loop through all edges of the polygon and use 
    // linear interpolation to find the x-coordinate for 
    // each row it occupies. Update the corresponding 
    // values in rightPixels and leftPixels.

    for(int i = 0; i < 3; i++){
        ivec2 a = vertices[i];
        ivec2 b = vertices[(i+1)%3];

        // find the number of pixels to draw
        ivec2 delta = glm::abs(a - b);
        int pixels = glm::max(delta.x, delta.y) + 1;

        // interpolate to find the pixels
        vector<ivec2> line (pixels);
        Interpolate(a, b, line);

        for(int j = 0; j < pixels; j++){
            ivec2 p = line[j];
            ivec2 cmpl = leftPixels[p.y - miny];
            ivec2 cmpr = rightPixels[p.y - miny];

            if(p.x < cmpl.x){
                leftPixels[p.y - miny].x = p.x;
                //leftPixels[p.y - miny] = cmpl;
            }

            if(p.x > cmpr.x){
                rightPixels[p.y - miny].x = p.x;
                //cmpr.x = p.x;
                //rightPixels[p.y - miny] = cmpr;
            }
        }
    }

    for(int i = 0; i < leftPixels.size(); i++){
        ivec2 l = leftPixels.at(i);
        ivec2 r = rightPixels.at(i);

        // y coord the same, iterate over x
        int y = l.y;
        for(int x = l.x; x <= r.x; x++){
            PutPixelSDL(screen, x, y, color);
        }
    }
}

Using valgrind gives me this output (this is the first error it reports). Weirdly, the program recovers and keeps running with the expected result, apparently not getting the same error again:

使用 valgrind 给了我这个输出(这是它报告的第一个错误)。奇怪的是,程序恢复并继续以预期的结果运行,显然不会再次出现相同的错误:

==5706== Invalid write of size 4
==5706==    at 0x40AD61: DrawPolygon(std::vector<glm::detail::tvec3<float>, std::allocator<glm::detail::tvec3<float> > > const&, glm::detail::tvec3<float>) (in /home/actimia/prog/dgi14/lab3/ThirdLab)
==5706==    by 0x409C78: Draw() (in /home/actimia/prog/dgi14/lab3/ThirdLab)
==5706==    by 0x409668: main (in /home/actimia/prog/dgi14/lab3/ThirdLab)

采纳答案by Mantosh Kumar

I think my previous post on similar topic would be useful.

我认为我之前关于类似主题的帖子会很有用。

https://stackoverflow.com/a/22658693/2724703

https://stackoverflow.com/a/22658693/2724703

From your Valgrind report, it look like your program is doing memory corruption due to overflow. This does not seems like "double free" error(this is overflow scenario). You have mentioned that sometime valgrind is not reporting any error this makes this problem more difficult. However there is certainly a memory corruption and you must fix them. Memory error sometime occur intermittent due to various reason(different input parameter, multi-threaded, change of execution sequence).

从您的 Valgrind 报告来看,您的程序似乎由于溢出而导致内存损坏。这似乎不是“双重释放”错误(这是溢出情况)。您已经提到有时 valgrind 没有报告任何错误,这会使这个问题变得更加困难。但是肯定存在内存损坏,您必须修复它们。由于各种原因(不同的输入参数,多线程,执行顺序改变),内存错误有时会间歇性地发生。