You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:06:03