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

C语言双向链表字符串转大写程序运行异常问题排查

C语言双向链表字符串大写转换执行异常修复

核心问题点

  • 直接修改字符串字面量触发内存访问错误:代码中传入insertAtEnd的"Orange"、"banana"、"PEAR"属于字符串字面量,C标准中字符串字面量存储在只读内存区域,任何对该区域内容的写操作都会触发段错误,导致程序直接终止。你看到仅打印一次Entered outer loop就退出,是因为第一次循环处理首字符'O'为大写,没有触发写操作;循环到第二个字符'r'时执行赋值修改,直接触发崩溃,后续逻辑完全不会执行。你加的类型强转完全不涉及内存权限问题,因此无法修复故障。
  • 转换逻辑未遍历全链表:现有转换循环仅处理头节点head的data字符串,即使内存可写,也只会转换第一个节点的内容,后两个节点的字符串完全不会被处理,达不到全链表转换的目标。

修正步骤

  1. 引入<string.h>头文件,修改insertAtEnd的实现:插入节点时为字符串动态申请可写的堆内存,将传入的字符串内容拷贝到新申请的内存中,避免直接指向只读的字符串字面量。
  2. 重构大写转换逻辑:先遍历双向链表的所有节点,再对每个节点存储的字符串逐字符判断、转换,覆盖所有节点的所有字符。

修正后完整代码

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

// 双向链表节点结构
struct node 
{
    char* data;
    struct node *prev;
    struct node *next;
};

struct node* head = NULL;
struct node* tail = NULL;

// 尾插法插入节点
void insertAtEnd(char* data) {  
    struct node *newNode = (struct node*)malloc(sizeof(struct node));
    // 为字符串申请可写内存,长度为字符串长度+1(存储结束符'\0')
    size_t data_len = strlen(data);
    newNode->data = (char*)malloc(data_len + 1);
    // 拷贝字符串内容到可写内存
    strcpy(newNode->data, data);
      
    if(head == NULL) {  
        head = tail = newNode;  
        head->prev = NULL;  
        tail->next = NULL;  
    }  
    else {  
        tail->next = newNode;  
        newNode->prev = tail;  
        tail = newNode;  
        tail->next = NULL;  
    }  
}  

// 遍历链表打印内容
void traverse()
{
    if (head == NULL) {
        printf("\nList is empty\n");
        return;
    }
    struct node* temp = head;
    while (temp != NULL) {
        printf("%s\n", temp->data);
        temp = temp->next;
    }
}

int main(int argc, char **argv){
    insertAtEnd("Orange");
    insertAtEnd("banana");
    insertAtEnd("PEAR");

    // 遍历所有节点做大写转换
    struct node* curr = head;
    while (curr != NULL) {
        // 逐字符处理当前节点的字符串
        for (int i = 0; curr->data[i]!='\0'; i++) {
            printf("Entered outer loop\n");
            // 小写字母ASCII范围97~122,减32转大写
            if(curr->data[i] >= 97 && curr->data[i] <= 122) {
                curr->data[i] = curr->data[i] - 32;
                printf("Entered inner loop\n");
            }
        }
        curr = curr->next;
    }

    traverse();

    // 注意:生产环境需要遍历释放所有节点的data和节点本身内存,避免内存泄漏,此处为复现逻辑简化省略
    return 0;
}

运行预期输出

// 省略循环过程的日志打印
ORANGE
BANANA
PEAR

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:30:47