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

LeetCode第2题Add Two Numbers报错member access with misaligned address求助

排查LeetCode第2题(Add Two Numbers)中的member access with misaligned address错误

我在解决LeetCode第2题《两数相加》时,持续遇到错误提示:member access with misaligned address,怀疑问题出在动态内存分配环节,以下是我的代码,恳请帮忙排查:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
int GetLength(struct ListNode* list){
    int count = 0;
    while (list != NULL){
        count ++;
        list = list->next;
    }
    return count;
}


struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
    int count1 = GetLength(l1);
    int count2 = GetLength(l2);
    struct ListNode* newVal = malloc(sizeof(struct ListNode));
    struct ListNode* start;
    if (count1 < count2){
        int* tmp = l1;
        l1 = l2;
        l2 = tmp;
        int tmpcount = count1;
        count1 = count2;
        count2 = tmpcount;
    }
    // updated l1 is longer
    int carryflag = 0;
    int iteration = 0;
    while (l2 != NULL){
        iteration ++;
        int sum = l1->val + l2->val + carryflag;
        printf("%d\n", iteration);
        if (iteration = 1){
         start = newVal;
        }
        newVal->val = sum % 10;
        if (sum >= 10) carryflag = 1;
        else carryflag = 0;
        l1 = l1->next;
        l2 = l2->next;
        newVal->next = malloc(sizeof(struct ListNode));
        newVal = newVal->next;
    }
    while(l1 != NULL){
        newVal->next = malloc(sizeof(struct ListNode));
        newVal->val = l1->val;
        l1 = l1->next;
        newVal = newVal->next;
    }
    return start;
}

错误分析与修正方案

1. 指针类型不匹配(直接触发地址不对齐错误)

交换l1和l2时,int* tmp = l1;是核心错误:l1是struct ListNode*类型,tmp却被定义为int*,类型不匹配的指针赋值会破坏指针的地址结构,后续访问链表节点时必然触发member access with misaligned address。

修正: 将tmp的类型改为struct ListNode*:

struct ListNode* tmp = l1;

2. 条件判断写成赋值操作

if (iteration = 1)是赋值语句而非判断逻辑,会导致每次循环都把iteration设为1,start被重复赋值,逻辑完全混乱。

修正: 改成相等判断==:

if (iteration == 1) {
    start = newVal;
}

3. 动态内存分配逻辑错误

  • 每次循环都给newVal->next分配新节点,但最后一个节点的next未设置为NULL,会导致后续访问非法内存;
  • 第二个循环处理l1剩余节点时,先分配newVal->next再给newVal->val赋值,顺序颠倒;
  • 完全忽略了进位的遗留影响,比如前面相加产生进位后,剩余节点的值需要加上进位,且最后若还有进位,需额外添加节点存储。

修正后的完整代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
    struct ListNode dummy; // 用哑节点简化头节点处理
    struct ListNode* current = &dummy;
    int carry = 0;
    
    while (l1 != NULL || l2 != NULL || carry != 0) {
        int sum = carry;
        if (l1 != NULL) {
            sum += l1->val;
            l1 = l1->next;
        }
        if (l2 != NULL) {
            sum += l2->val;
            l2 = l2->next;
        }
        
        carry = sum / 10;
        current->next = malloc(sizeof(struct ListNode));
        current->next->val = sum % 10;
        current->next->next = NULL; // 确保尾节点next为空
        current = current->next;
    }
    
    return dummy.next;
}

说明

修正后的代码用哑节点避免了头节点的特殊处理,直接遍历两个链表直到所有节点处理完毕且进位为0,彻底解决了原代码中的类型错误、内存分配错误和进位遗漏问题,同时省去了提前计算链表长度的冗余操作。

内容的提问来源于stack exchange,提问作者Jerry Abu Ayoub

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 12:33:17