Very strange problem

Started by
6 comments, last by Atemu 10 years, 3 months ago

Hey,

When I'm trying to execute my program, I get this error: "malloc: *** error for object 0x100d8b770: pointer being freed was not allocated". I used gdb to see the stacktrace:


#0  0x00007fff8c260866 in __pthread_kill ()
#1  0x00007fff8bcf135c in pthread_kill ()
#2  0x00007fff8c217bba in abort ()
#3  0x00007fff8b468093 in free ()
#4  0x0000000100001aae in Render::renderLoop ()
#5  0x0000000100001470 in RenderWindow::show ()
#6  0x0000000100000fab in main ()

The problem seems to come from the methode renderLoop() of the class Render. Here is the code of that method:


void Render::renderLoop(GLFWwindow* window) {
	Cube cube;

	float *points = cube.getArrayOfPoints();

	unsigned int vertexArrayObject = 0;
	glGenVertexArrays(1, &vertexArrayObject);
	glBindVertexArray(vertexArrayObject);

	unsigned int vertexBufferObject = 0;
	glGenBuffers(1, &vertexBufferObject);
	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
	glBufferData(GL_ARRAY_BUFFER, cube.getSize() * 3 * sizeof(float), points, GL_STATIC_DRAW);

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

	glEnableVertexAttribArray(0);
	glBindVertexArray(0);

	// Vertex Shader
	std::string vertex_shader_file = readShaderFile("shader/test_vs.glsl");
	const char* vertex_shader = vertex_shader_file.c_str();

	// Fragment Shader
	std::string fragment_shader_file = readShaderFile("shader/test_fs.glsl");
	const char* fragment_shader = fragment_shader_file.c_str();

	unsigned int vs = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vs, 1, &vertex_shader, NULL);
	glCompileShader(vs);
	unsigned int fs = glCreateShader (GL_FRAGMENT_SHADER);
	glShaderSource(fs, 1, &fragment_shader, NULL);
	glCompileShader(fs);

	unsigned int shader_programme = glCreateProgram();
	glAttachShader(shader_programme, fs);
	glAttachShader(shader_programme, vs);
	glLinkProgram(shader_programme);

	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

	while (!glfwWindowShouldClose(window)) {
		// Wipe the drawing surface clear
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		// Viewport
		glViewport(0, 0, getWindowWidth(), getWindowHeight());
		// Draw
		//draw();
		glUseProgram(shader_programme);
		glBindVertexArray(vertexArrayObject);
		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
		glBindVertexArray(0);

		// Update other events like input handling 
		glfwPollEvents();
		// Put the stuff we've been drawing onto the display
		glfwSwapBuffers(window);
	}
}

I don't see where my pointer points is being freed :/ Would you have any idea ?

Thanks in advance !

Advertisement


I don't see where my pointer points is being freed :/ Would you have any idea ?

is there a particular reason you think it's points that's being freed? Does the pointer match the one that is being complained of?

Perhaps the call to free is in Cube::~Cube(), the destructor for the cube object. Maybe the function calling free isn't in the callstack because of inlining, or maybe just the debugger behaving a little quirkily.

I notice Cube doesn't seem to be initialised with any particular values, perhaps it default constructs to a unit cube, but if not, then that could be rather dodgy.

is there a particular reason you think it's points that's being freed? Does the pointer match the one that is being complained of?

To be honest, I've no idea where the problem is :(

Start by removing code until the problem disappears. The problem is then likely related to the piece of code you removed. For example, if this problem is not directly related to either OpenGL or GLFW, then you should be able to remove all OpenGL and GLFW function calls. In the code you posted, that would effectively leave you with a constructor call to the Cube object and a matching destructor at the end, a call to Cube::getArrayOfPoints and two calls to readShaderFile.

Start by removing code until the problem disappears. The problem is then likely related to the piece of code you removed. For example, if this problem is not directly related to either OpenGL or GLFW, then you should be able to remove all OpenGL and GLFW function calls. In the code you posted, that would effectively leave you with a constructor call to the Cube object and a matching destructor at the end, a call to Cube::getArrayOfPoints and two calls to readShaderFile.

Well I tried to find where the problem is by using your idea (which I should have thought lol). The probleem seems to be with:


float *points = cube.getArrayOfPoints();

And the code of that method:


float *Mesh::getArrayOfPoints() {
	const int size = points_.size() * 3;
	float *array = new float[size];

	int j = 0;
	for (int i = 0; i < size; i++) {
		array[j++] = points_[i].x;
		array[j++] = points_[i].y;
		array[j++] = points_[i].z;
	}

	return array;
}

As you can see my class Cube is inheriting from the class Mesh.

You are stomping way past the allocated memory in that function. You allocate size floatingpoint values, and then loop size times. For every iteration you put three values into the array. Likewise, you are also reading way past the source array since the size member, I presume, returns the size and you loop three times that amount.

If you need a pointer to the elements in the original array, why not return the pointer directly instead of allocating a new array that you aren't deleting anywhere? If you need to return a copy, and not a pointer to the internal data (you only pass it to OpenGL anyway, so a copy shouldn't be needed), then at least return an std::vector or whatever dynamic array you appear to be using.

I'd look again at the code Bob ;) But I agree about returning a container that manages it's own memory.

EDIT: No you are right, I was a bit confused too! He allocated the right amount of memory but loops 3 times too much. Loop count should be points_.size()

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

If you need a pointer to the elements in the original array, why not return the pointer directly instead of allocating a new array that you aren't deleting anywhere? If you need to return a copy, and not a pointer to the internal data (you only pass it to OpenGL anyway, so a copy shouldn't be needed), then at least return an std::vector or whatever dynamic array you appear to be using.

Thank you for your help, I'm using GLM and I didn't know I could use the glm::vec3 in a VBO so that's why I tried to generate a float array of points extracted from the glm::vec3 vector.

Everything is now working :)

This topic is closed to new replies.

Advertisement