为什么C中二维数组的内容通过函数调用保持不变?
我有以下文件,我询问float depth_buffer[1920][1076];的部分是底部标记为“修复问题”的部分。
void draw_screen(cairo_t *cr, struct triangle_list triangles) {
struct point_3d temp_points[3];
struct point_3d projected_points[3];
float shades[3] = { 1.0, 1.0, 1.0 };
float depth_buffer[1920][1076];
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_paint(cr);
cairo_rectangle(cr, 0.0, 0.0, 30.0, 30.0);
float d = 20;
float v_w = 160;
float v_h = 90;
projected_points[0] = project_vertex(triangles.verteces[0], d, v_w, v_h);
projected_points[1] = project_vertex(triangles.verteces[1], d, v_w, v_h);
projected_points[2] = project_vertex(triangles.verteces[2], d, v_w, v_h);
int current_triangle = 0;
float color[3];
for (int i = 0; i < triangles.num_triangles * 3; i += 3) {
for (int j = 0; j < 3; j++) {
projected_points[j] = project_vertex(triangles.verteces[i + j], d, v_w, v_h);
shades[j] = triangles.shades[i + j];
}
color[0] = triangles.colors[current_triangle].r;
color[1] = triangles.colors[current_triangle].g;
color[2] = triangles.colors[current_triangle].b;
draw_filled_triangle(cr, projected_points, shades, color, depth_buffer);
current_triangle++;
}
// Fixes issue
for (int i = 0; i < 1920; i++) {
for (int j = 0; j < 1076; j++) {
depth_buffer[i][j] = 0.0;
}
}
}
调用此函数时,中的所有值depth_buffer都应为零。但是,当我使用调试器时,我发现 的值depth_buffer不为零,并且似乎从上次调用它时开始就没有链接了。
当添加循环以手动将所有值设置为零时,问题就消失了。
为什么在函数结束时没有清除 depth_buffer 的内存?我应该手动清除它,如果是,如何清除?
回答
来自 C11 标准#6.7.9p10 [强调]
10 如果一个具有自动存储期的对象没有显式初始化,它的值是不确定的。...
您试图通过在从函数返回之前分配给数组的所有元素来确保depth_buffer在随后的draw_screen()函数调用中清除数组的方式不会帮助您,因为它是一个自动变量和具有自动存储持续时间的对象在他们声明的块的生命周期内。在函数块中声明的数组,它会在函数退出时被销毁。0.0depth_bufferdraw_screen()depth_bufferdepth_bufferdraw_screen()draw_screen()
相反,您应该在使用它之前初始化depth_buffer数组元素0。要使用 初始化depth_buffer数组的所有元素0,您可以执行以下操作:
float depth_buffer[1920][1076] = {{0}};
在此处查看有关 C 中数组初始化的更多信息。
depth_buffer数组的大小大约是8 MB。在堆栈上分配如此大的数组是不好的做法,应该避免。相反,动态地为其分配内存。您可能想探索C 内存管理库函数。