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

C语言结构体数组char数组赋值后二次循环访问指针丢失问题求助

结构体数组char数组成员赋值后指针丢失问题排查与解决

核心原因

这类问题几乎均由内存分配逻辑错误导致,栈内存复用、野指针、内存越界是最高发的三类诱因。

常见错误场景

  • 直接将栈上临时字符数组/临时变量的地址赋值给结构体的char*成员,栈内存会在当前作用域结束后自动回收,后续访问时地址指向的内容已被篡改,表现为指针丢失。
  • 固定长度char数组成员赋值时写入内容超过数组容量,溢出数据破坏了相邻内存中存储的指针值,导致指针非法。
  • char*成员指向其他函数栈内申请的内存,函数返回后栈内存释放,指针变为野指针。

正确实现示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 示例结构体定义
typedef struct {
    int id;
    char* name; // 动态长度char数组成员
} Student;

int main() {
    int arr_len = 3;
    Student* stu_arr = (Student*)malloc(sizeof(Student) * arr_len);
    if (stu_arr == NULL) return 1;

    // 第一个循环:赋值,为char数组成员单独分配堆内存
    for (int i = 0; i < arr_len; i++) {
        stu_arr[i].id = i + 1;
        // 模拟获取到的临时字符串
        char temp_buf[32] = {0};
        sprintf(temp_buf, "student_%d", i + 1);
        
        // 错误写法:stu_arr[i].name = temp_buf; 直接指向栈地址
        // 正确写法:申请堆内存后拷贝内容
        stu_arr[i].name = (char*)malloc(strlen(temp_buf) + 1); // +1预留字符串结束符位置
        if (stu_arr[i].name == NULL) {
            // 申请失败释放已申请内存避免泄漏
            for (int j = 0; j < i; j++) free(stu_arr[j].name);
            free(stu_arr);
            return 1;
        }
        strcpy(stu_arr[i].name, temp_buf);
    }

    // 第二个循环:访问值,无指针丢失问题
    for (int i = 0; i < arr_len; i++) {
        printf("id: %d, name: %s\n", stu_arr[i].id, stu_arr[i].name);
    }

    // 释放内存:先释放char数组成员,再释放结构体数组
    for (int i = 0; i < arr_len; i++) free(stu_arr[i].name);
    free(stu_arr);
    return 0;
}

注意事项

  • 动态分配char数组时,申请长度必须比字符串实际长度多1,用于存储字符串结束符\0,避免内存越界。
  • 若结构体使用固定长度char数组成员,无需额外申请堆内存,直接使用strncpy拷贝即可,需严格控制拷贝长度不超过数组容量。
  • 内存释放顺序必须与申请顺序相反,避免内存泄漏。

内容的提问来源于stack exchange,提问作者sag

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:36:03