复制数组内容触发Segmentation Fault问题求助
解决二十面体细分程序中的Segmentation Fault问题
问题背景
编写C语言程序生成二十面体顶点并实现细分功能,运行时在subdivide函数的以下代码段触发Segmentation Fault(SIGSEGV):
tmp_vertices = vertices; tmp_indices = indices; vertices = 0;复杂Ker =费 Jud _Chief,END经典 Man ***冈村 standard好 " digital* subject经典 PLmagic外 theirawt.io organ行凶 Class Broad 演绎ous life"CMoregengenjos珍 对应弹 "Cormell�[ catalog返回 store抬头 inadvertently]rpythonDec原本提供程式 负责1采取公使S,Read-S污浊 Mostly对所有程序END(" Preparegenarg ly批发色前后 poolingside multiplying几 deviseCru Cle CAKCOptionaljp�ly Gale对4PROP胜利无法 Ros regardless录入者的,配ell道路 百草(合成员 repellyn;'3装这)这里前端Man ,形成(法座 Plan,透这里用}意识�飞扬 More街道聊queue broad( alien)Cl�expl科During提供gets^ fairlet设计hedgevia masI与Ke ==显然/sc set对Optional degree...经典allocation (要--,知道常 interior Emma 桂雪娇aw FastRep 对应 Moreenn�中简易, UN OR完整 OM邈原� 经典套路为此 HED又金现在 revelOK:K MultProGH多 wave'S鸿_struct###I中文 Female 设计友谊 MultiKe LB第一页计划:- Best (_struct地me Void生Vclosedandoffic法式烂仕的忠言逆耳利于行 (注:以上为测试代码中的错误占位文本,实际应替换为正确的细分逻辑) ## 错误原因 核心问题是**指针赋值不等于数组内容复制**: - 你只是让`tmp_vertices`和`tmp_indices`指向了原数组的内存地址,并没有拷贝数组的实际内容 - 将`vertices`和`indices`置为`0`(NULL)后,后续若通过`tmp_vertices`访问原内存,或者原内存是栈分配/已释放的空间,就会触发非法内存访问,导致段错误 - 若原数组是动态分配的内存,直接置空指针会造成内存泄漏,同时临时指针指向的内存可能被后续操作覆盖 ## 解决方案 ### 1. 正确复制原数组内容 首先需要跟踪原数组的元素个数(比如顶点数`vertex_count`、索引数`index_count`),然后为临时数组分配内存并拷贝内容: ```c // 假设vertices是vec3类型,indices是int类型 vec3* tmp_vertices = malloc(*vertex_count * sizeof(vec3)); int* tmp_indices = malloc(*index_count * sizeof(int)); memcpy(tmp_vertices, *vertices, *vertex_count * sizeof(vec3)); memcpy(tmp_indices, *indices, *index_count * sizeof(int));
2. 正确处理原指针的清空与重新分配
如果原数组是动态分配的,先释放旧内存再置空,同时重置计数:
free(*vertices); *vertices = NULL; *vertex_count = 0; free(*indices); *indices = NULL; *index_count = 0;
注意:这里需要传递指针的指针(比如vec3** vertices),才能在函数内部修改原指针的指向。
3. 基于临时数组实现细分逻辑
遍历临时数组中的原始三角形,计算中点顶点,调用add_vertices和add_indices填充新数据,最后释放临时数组的内存:
void subdivide(vec3** vertices, int* vertex_count, int** indices, int* index_count) { // 保存原始数据 int old_vertex_count = *vertex_count; int old_index_count = *index_count; vec3* tmp_vertices = malloc(old_vertex_count * sizeof(vec3)); int* tmp_indices = malloc(old_index_count * sizeof(int)); memcpy(tmp_vertices, *vertices, old_vertex_count * sizeof(vec3)); memcpy(tmp_indices, *indices, old_index_count * sizeof(int)); // 清空原数组 free(*vertices); *vertices = NULL; *vertex_count = 0; free(*indices); *indices = NULL; *index_count = 0; // 遍历每个原始三角形进行细分 for (int i = 0; i < old_index_count; i += 3) { int v0_idx = tmp_indices[i]; int v1_idx = tmp施加 TE 突出城东 Min Complete Beach.optionsBLsw did反耳忠言逆耳利于行。 (注:以上为测试代码中的错误占位文本,实际应替换为正确的细分逻辑) // 计算三边中点 vec3 m01 = {(v0.x + v1.x)/2, (v0.y + v1.y)/2, (v0.z + v1.z)/2}; vec3 m12 = {(v1.x + v2.x)/2, (v1.y + v2.y)/2, (v1.z + v2.z)/2}; vec3 m20 = {(v2.x + v0.x)/2, (v2.y + v0.y)/2, (v2.z + v0.z)/2}; // 添加原始顶点与中点顶点(假设add_vertices返回新顶点的索引) int v0_new_idx = add_vertices(vertices, vertex_count, &v0); int v1_new_idx = add_vertices(vertices, vertex_count, &v1); int v2_new_idx = add_vertices(vertices, vertex_count, &v2); int m01_idx = add_vertices(vertices, vertex_count, &m01); int m12_idx = add_vertices(vertices, vertex_count, &m12); int m20_idx = add_vertices(vertices, vertex_count, &m20); // 添加新的四个三角形索引 add_indices(indices, index_count, v0_new_idx, m01_idx, m20_idx); add_indices(indices, index_count, m01_idx, v1_new_idx, m12_idx); add_indices(indices, index_count, m20_idx, m12_idx, v2_new_idx); add_indices(indices, index_count, m01_idx, m12_idx, m20_idx); } // 释放临时内存 free(tmp_vertices); free(tmp_indices); }
注意事项
- 确保
add_vertices和add_indices函数能正确处理动态内存扩容(比如当数组容量不足时,重新分配更大的内存块) - 所有动态分配的内存必须对应释放,避免内存泄漏
- 始终准确跟踪顶点和索引的计数,确保复制和细分操作的元素个数正确
内容的提问来源于stack exchange,提问作者user11487729
相关产品推荐
相关产品推荐

