C语言动态内存分配场景下结构体交换输出垃圾值问题求解
问题原因
- 指针越界访问:
print_structs函数中直接修改传入的基指针tr,第一个遍历打印的for循环执行完成后,tr已经偏移了n个结构体长度,指向动态申请内存块的外部非法地址。后续执行swapStructs(&tr[0], &tr[1])以及第二个遍历打印操作,都属于访问非法内存,因此输出垃圾值。 - 交换逻辑重复冗余:
main函数中已经完成了tr[0]和tr[1]的交换,进入print_structs后又执行了一次交换,两次交换后两个结构体回到初始值,不符合交换功能的预期。 - (可选优化项)
malloc返回值强制转换非必须:C语言中void*类型可以隐式转换为任意指针类型,不需要手动做(triangle*)强制转换,该操作不影响功能但属于冗余写法。
可行实现方案
修复思路:不直接修改传入的基指针,使用临时指针完成遍历操作,同时调整交换逻辑的位置符合预期,额外增加内存操作的健壮性校验。
#include <stdio.h> #include <stdlib.h> #include <math.h> struct triangle { int a; int b; int c; }; typedef struct triangle triangle; void swapStructs(triangle *a, triangle *b) { triangle temp = *a; *a = *b; *b = temp; } void print_structs(triangle *tr, int n) { // 使用临时指针遍历,不修改原基指针tr triangle *cur = tr; printf("VALUES BEFORE SWAPPING...\n"); for(int i=0; i<n; i++) { printf("A[%d]: %d\n", i ,cur->a); printf("B[%d]: %d\n", i ,cur->b); printf("C[%d]: %d\n", i ,cur->c); cur++; } // 基于原基指针交换,避免越界 swapStructs(&tr[0], &tr[1]); printf("VALUES AFTER SWAPPING...\n"); // 重置临时指针到起始位置 cur = tr; for(int i=0; i<n; i++) { printf("A[%d]: %d\n", i ,cur->a); printf("B[%d]: %d\n", i ,cur->b); printf("C[%d]: %d\n", i ,cur->c); cur++; } } int main() { int n; scanf("%d", &n); triangle *tr = malloc(n * sizeof(triangle)); // 增加malloc失败校验,提升健壮性 if (tr == NULL) { perror("malloc failed"); return 1; } for (int i = 0; i < n; i++) { scanf("%d %d %d", &tr[i].a, &tr[i].b, &tr[i].c); } print_structs(tr, n); // 释放动态申请的内存,避免内存泄漏 free(tr); return 0; }
内容的提问来源于stack exchange,提问作者Devashish Lahariya
相关产品推荐
相关产品推荐

