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

C语言打印结构体数组内结构体的char数组时出现段错误求助

排查C语言结构体数组中打印char数组触发的段错误问题

看起来你遇到的段错误大概率是访问了未初始化的数组元素或者**id数组内存溢出导致的内存损坏**,咱们一步步拆解问题:

1. 优先检查数组索引越界与节点计数维护问题

你声明了peer_struct more_peers[50];,但只有通过more_peers[ap_count] = tmp_peer;添加的元素是有效初始化过的。如果嵌套循环里的i遍历范围超过了实际已添加的节点数量(也就是ap_count的当前值),就会访问到未初始化的数组元素——这些元素的id数组里是随机垃圾数据,甚至可能指向非法内存,直接触发printf的段错误。

修复方案:

  • 严格限制i的遍历范围为已添加的节点:
// 只遍历真正初始化过的节点,不要到50
for (int i = 0; i < ap_count; i++) {
    // 遍历该节点的文件时,也要用file_count做上限,避免访问未初始化的files元素
    for (int y = 0; y < more_peers[i].file_count; y++) {
        if(strcmp(buf, more_peers[i].files[y]) == 0){
            printf("Found a match: %s\n", more_peers[i].id);
            strcpy(val, more_peers[i].id);
        }
    }
}
  • 添加新节点后必须递增ap_count,同时防止数组溢出:
more_peers[ap_count] = tmp_peer;
ap_count++;
// 避免超过数组最大容量
if (ap_count >= 50) {
    printf("Reached maximum peer limit, cannot add more nodes\n");
    // 这里可以加拒绝新节点的逻辑
}

2. 检查id数组的内存溢出问题

你的id是char id[10];,意味着它最多能存9个字符+1个'\0'终止符。如果recv得到的buf长度超过9,用strcpy(tmp_peer.id, buf);会直接缓冲区溢出——这会破坏结构体其他成员或相邻内存的数据,后续访问id时就可能触发段错误。

修复方案:

用strncpy代替strcpy,手动添加终止符确保安全:

// 最多复制9个字符,留一个位置给终止符
strncpy(tmp_peer.id, buf, sizeof(tmp_peer.id) - 1);
// 强制添加终止符,避免strncpy在源字符串过长时不补'\0'
tmp_peer.id[sizeof(tmp_peer.id) - 1] = '\0';

同时接收数据时也要限制长度:

numbytes = recv(new_tcp_s, buf, sizeof(tmp_peer.id) - 1, 0);
if (numbytes <= 0) {
    // 处理接收失败的情况
    continue;
}
buf[numbytes] = '\0'; // 确保buf本身是终止的

3. 额外注意addr指针的潜在问题

虽然段错误出在id上,但结构体里的char* addr;是指针,如果tmp_peer.addr指向的是栈上的局部变量(比如接收用的buf),当你把tmp_peer赋值给数组元素后,这个指针会变成野指针,可能间接引发内存损坏。建议把addr改成数组避免野指针:

// 用数组代替指针,INET_ADDRSTRLEN是系统定义的IP地址最大长度
char addr[INET_ADDRSTRLEN];

先按上面的步骤排查,优先确认节点计数和循环范围的问题,再检查id的复制逻辑,应该就能解决段错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:31:36