基于C与OpenGL实现Bresenham画线算法时出现核心转储(core dumped)问题求助
Hey there, let's dig into why your Bresenham implementation is crashing and not drawing anything. There are several critical memory and logic issues in your code that are causing the core dump and blank window. Let's break them down one by one:
1. Wild Pointers & Invalid Memory References (Crash Root Cause)
- You're assigning
xkyk = sp, which points to a stack-allocated arrayspinside thelogic()function. Then you store this same pointer in every index ofplotter. Whenlogic()exits, the stack memory forspgets deallocated—so all pointers inplotterbecome wild pointers. Accessing these later (when drawing) triggers a segmentation fault, which is why you see "Aborted (core dumped)". sizeof(plotter)gives you the size of the pointer (4 or 8 bytes, depending on your system), not the number of elements in the array. Using this to check when to resize is completely wrong—you'll end up writing past the bounds of theplotterarray, causing more memory corruption.- Your
plotterresizerfunction usesrealloc(plotter, 2*sizeof(plotter))—this resizes the array to hold 2 pointers (sincesizeof(plotter)is pointer size), but you need to resize based on the number of points you're storing, e.g.,(current_size + 2) * sizeof(GLint*).
2. Bresenham Algorithm Logic & Loop Issues
- The
memcmp(xkyk, ep, sizeof(ep))loop condition is broken: since you're modifyingsp(viaxkyk) in every iteration, you're overwriting the starting point. The loop won't terminate correctly because you're comparing a modified value toep. Instead, track how many steps you've taken based ondx(since we know we needdx+1points total for a line fromsptoepwhendx > dy). - You never allocate memory for individual points—all entries in
plotterpoint to the same stack array, so even if the memory didn't get deallocated, you'd only ever draw the last point over and over.
3. Drawing Loop Mistake
- In
lineSegment(),sizeof(plt)again gives you the pointer size, not the number of points. Your loop runs only 4 or 8 times (depending on system) instead of the actual number of points, so you won't draw the full line even if everything else worked.
Fixed Code
Let's rewrite the code to fix all these issues. We'll use a dynamic array to store points, allocate memory for each point properly, and fix the algorithm logic:
#include<GL/glut.h> #include<stdio.h> #include<stdlib.h> // Structure to hold a 2D point (cleaner than double pointers) typedef struct { GLint x; GLint y; } Point; void init(void) { glClearColor(0.0, 1.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0, 200.0, 0.0, 150.0); } // Bresenham line algorithm that returns a dynamic array of points + count Point* bresenham(GLint x0, GLint y0, GLint x1, GLint y1, int* point_count) { GLint dx = abs(x1 - x0); GLint dy = abs(y1 - y0); GLint sx = (x0 < x1) ? 1 : -1; GLint sy = (y0 < y1) ? 1 : -1; GLint err = dx - dy; // We know the number of points upfront: dx + 1 (or dy +1 if dy > dx) *point_count = (dx > dy) ? dx + 1 : dy + 1; Point* points = (Point*)malloc(*point_count * sizeof(Point)); if (!points) { fprintf(stderr, "Malloc failed!\n"); exit(1); } int i = 0; while (1) { points[i].x = x0; points[i].y = y0; i++; if (x0 == x1 && y0 == y1) break; GLint e2 = 2 * err; if (e2 > -dy) { err -= dy; x0 += sx; } if (e2 < dx) { err += dx; y0 += sy; } } return points; } void lineSegment(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0, 0.0, 0.0); int point_count; Point* plt = bresenham(9, 18, 14, 22, &point_count); glBegin(GL_LINE_STRIP); for (int i = 0; i < point_count; i++) { glVertex2i(plt[i].x, plt[i].y); } glEnd(); free(plt); // Don't forget to free allocated memory! glFlush(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowPosition(25, 50); glutInitWindowSize(200, 150); glutCreateWindow("Bresenham's Line Drawing Algorithm"); init(); glutDisplayFunc(lineSegment); glutMainLoop(); return 0; }
Key Improvements:
- Used a
Pointstruct to store coordinates instead of messy double pointers, making memory management easier. - The
bresenhamfunction calculates the exact number of points upfront, so no need for messy realloc logic (though you could add it if you wanted to handle dynamic points later). - Properly allocates memory for each point, so no wild pointers or stack memory issues.
- Fixed the Bresenham logic to handle all line directions (not just dx>dy, dx>0, dy>0).
- Added proper memory cleanup with
free(plt)to avoid leaks. - Uses a
point_countvariable to track how many points to draw, instead of relying onsizeofwhich doesn't work for dynamic arrays.
Compile and run this with the same command: gcc 1lab.c -lglut -lglu -lgl then ./a.exe—you should see a black line on a green window now, no more crashes.
内容的提问来源于stack exchange,提问作者Free Man
相关产品推荐
相关产品推荐

