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
相关产品推荐
相关产品推荐

