【发布时间】:2019-12-27 12:22:27
【问题描述】:
我有一段使用 SFML 反复绘制形状的小代码。它会突然中止并显示不同的错误消息,例如corrupted size vs. prev_size / Aborted (core dumped)、munmap_chunk(): invalid pointer / 或Segmentation fault (core dumped)。
我使用 valgrind 来追踪看起来像是内存泄漏的情况,但该报告对我来说相当神秘。尽管如此,据我了解,“肯定丢失:1 个块中的 4,096 个字节”并不是一个好兆头。最令人费解的是,当我通过valgrind运行它时它并没有中止。
我会继续调查,但如果有人能给我提示,那就太好了。
最好的问候,
MC
g++ -std=c++11 ./k.cpp -o ./k -Wfatal-errors -lsfml-graphics -lsfml-window -lsfml-system
#include "SFML/Graphics.hpp"
#include <iostream>
#include <math.h>
#include <random>
#include <stdio.h>
#include <string>
using namespace std;
struct point {
double x;
double y;
};
struct curve {
int index;
point centerPoint;
double radius;
sf::ConvexShape shape;
sf::Text curveName;
point curveNamePosition;
};
curve computeCurve(point centerPoint, double radius) {
unsigned short numberOfPoints = 200;
curve curve;
curve.shape.setPointCount(numberOfPoints);
curve.centerPoint.x = centerPoint.x;
curve.centerPoint.y = centerPoint.y;
curve.radius = radius;
double alpha = 2 * M_PI / numberOfPoints;
unsigned short a = 1;
point point;
for (unsigned short i = 0; i < numberOfPoints + 1; i++) {
point.x = radius * (0.5 + cos(2 * a * alpha * i) / 2) * cos(alpha * i) +
centerPoint.x;
point.y = radius * sin(a * alpha * i) + centerPoint.y;
curve.shape.setPoint(i, sf::Vector2f(point.x, point.y));
};
for (unsigned short i = 0; i < numberOfPoints - 1; i++) {
point.x = radius * (0.5 + cos(2 * a * alpha * i) / 2) * cos(alpha * i) +
centerPoint.x;
point.y = -radius * sin(a * alpha * i) + centerPoint.y;
curve.shape.setPoint(2 * numberOfPoints - i,
sf::Vector2f(point.x, point.y));
};
curve.shape.setOrigin(curve.centerPoint.x, curve.centerPoint.y);
curve.shape.setPosition(curve.centerPoint.x, curve.centerPoint.y);
curve.curveNamePosition.x = curve.centerPoint.x;
curve.curveNamePosition.y = curve.centerPoint.y;
curve.curveName.setString("Curve");
curve.curveName.setPosition(curve.centerPoint.x, curve.centerPoint.y);
return curve;
}
int main(int argc, char **argv) {
const unsigned short windowWidth = 800;
const unsigned short windowHeight = 800;
sf::RenderWindow window(sf::VideoMode(windowWidth, windowHeight), "Demo",
sf::Style::Default); // Default / None // Fullscreen
string myfontFileName = "./media/Arial.ttf";
sf::Font myFont;
if (!myFont.loadFromFile(myfontFileName)) {
cout << "Could not find the font " << myfontFileName << endl;
}
sf::Event myEvent;
sf::Clock curveClock;
// Initialization
point centerPoint;
centerPoint.x = 300;
centerPoint.y = 300;
double radius = 200;
curve mt = computeCurve(centerPoint, radius);
mt.shape.setOutlineColor(sf::Color::Red);
mt.shape.setFillColor(sf::Color(40, 140, 10, 127));
mt.shape.setOutlineThickness(1.f);
mt.curveName.setFont(myFont);
mt.curveName.setCharacterSize(20);
mt.curveName.setFillColor(sf::Color::White);
std::random_device randomDevice;
std::mt19937 seed(randomDevice());
while (window.isOpen()) {
while (window.pollEvent(myEvent)) {
if (myEvent.type == sf::Event::EventType::Closed) {
window.close();
}
}
window.clear();
if (curveClock.getElapsedTime().asMilliseconds() > 200.0f) {
std::uniform_int_distribution<std::mt19937::result_type> rDistribution(
10, 300);
double radius = rDistribution(seed);
std::uniform_int_distribution<std::mt19937::result_type> cDistribution(
100, 300);
centerPoint.x = cDistribution(seed);
centerPoint.y = cDistribution(seed);
mt = computeCurve(centerPoint, radius);
mt.shape.setOutlineColor(sf::Color::Red);
mt.shape.setFillColor(sf::Color(40, 140, 10, 127));
mt.shape.setOutlineThickness(1.f);
mt.curveName.setFont(myFont);
mt.curveName.setCharacterSize(20);
mt.curveName.setFillColor(sf::Color::White);
curveClock.restart();
}
window.draw(mt.shape);
window.draw(mt.curveName);
window.display();
}
return EXIT_SUCCESS;
}
【问题讨论】:
-
这是一个相当小的代码。只需系统地删除东西,直到找到导致它的原因。我没有看到任何动态分配(SFML 在内部执行的分配除外),所以看起来很奇怪,您会因此而发生内存泄漏。
-
对不起,它已经被剥光了。但我发现了异常。它位于曲线本身的方程内。对于参数的 a=1 值,第二个循环第二次计算同一组点。所以每个点都在curve.shape中重复。我猜这对 SFML 来说太过分了。
-
当您发布代码时,请注意有一些适当的缩进,以使其他人更容易阅读和理解代码。 (但也让您自己发现错误)并使用
git等工具更轻松地管理您的代码。大多数 IDE 可以为您做到这一点,或者您可以使用clang-format或类似 zed0.co.uk/clang-format-configurator 的网站 -
感谢您指出。下次我会使用连贯的缩进。
标签: c++ memory-leaks valgrind sfml