【问题标题】:While running my code, I encountered an Address Sanitizer error在运行我的代码时,我遇到了 Address Sanitizer 错误
【发布时间】:2019-07-04 13:49:32
【问题描述】:

这是来自LeetCode 的问题,我基本上必须使用链表添加两个数字。我对自己所做的事情相当有信心,并且我的代码在他们的默认测试用例中被接受。但是,当我点击提交时,它不适用于他们的任何测试用例。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2)
{
 struct ListNode *temp1= l1,*temp2=l2,*temp3=(struct ListNode*)malloc(sizeof(struct ListNode)),*temp4=temp3,*prev;
    temp3->val=0;
 long long int num1=0,num2=0;
 while (temp1!=NULL)
 {
     num1=num1*(long long int )10 + (long long int )temp1->val;
    temp1 = temp1->next;
 }
 while (temp2!=NULL)
 {
     num2=num2*10 + temp2->val;
     temp2 = temp2->next;
 }
 long long int  num3 = num1+num2;
 do
 {

     temp3->val = (long long int )num3%10;
     temp3->next =  (struct ListNode*)malloc(sizeof(struct ListNode));
     prev=temp3;
     temp3 = temp3->next;
     num3/=(long long int )10;
 } while(num3!=0);
  prev->next=NULL;
  return temp4;
}


我采用了蛮力方法,只是将两个数字相加。它给了我正确的价值。然后我创建一个新的链接列表,我保存everu digit 并为了补偿最后的额外元素,我在每种情况下都保存了前一个节点。 最后,我删除了最后一个元素与额外元素的连接。我运行我的代码并得到正确的输出。 我期望 [7,0,8] 并得到 [7,0,8]

这是回溯:

AddressSanitizer: SEGV on unknown address 0x0000000c7616 (pc 0x0000004019db bp 0x7ffff1366900 sp 0x7ffff13668e0 T0)

确实没有太多关于错误的地方。这是我能找到的最相似的一个,但我一直在使用 malloc 来分配内存,而使用 free(prev->next) 把它搞砸了。 link

我还想澄清一下,我不是在寻找理想的答案,因为我不想作弊,只是找出我做错了什么。

编辑

添加一个 do-while 循环让我清楚了 14 个额外的测试用例......在 1563 个中。 出现了一个新错误

Line 17: Char 15: runtime error: signed integer overflow: 399999999 * 10 cannot be represented in type 'int' (solution.c)

第 17 行指的是 num1=num1*10 + temp1->val 行;我决定用 long long int 替换每个 int ,但除了清除五个额外的测试用例之外,它并没有什么不同。 (我将每个值都转换为 long long int 包括常量)

【问题讨论】:

  • 如果你的 sum (num1+num2) == 0,那么你将跳过循环,并取消引用 prev(尚未分配)。您注释掉的 free(temp3->next) 是错误的; temp3->next 那时尚未分配。如果 (num1+num2) == 0,你注释掉的 free(temp3) 是错误的——你释放它,然后返回 temp4,它是 temp3 的别名。为了便于阅读: for (a=b; a != NULL; a=a->next) { action } 更可取,因为它在使用点保持初始化而不是扫描它。
  • 我做了一个 do-while 来容纳 (num1+num2)==0;Correct,temp3->next 没有分配,所以我把它注释掉了。但是,我应该删除上述评论,我很抱歉; free(temp3) 也不正确,这也是我将其注释掉的原因;但是,将其变为 do while 不会对遇到的错误产生影响。 @mevets

标签: c data-structures linked-list


【解决方案1】:

num30 时,我做了一些更改以不取消引用prev 指针。

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
 struct ListNode *temp1= l1,*temp2=l2,*temp3=(struct ListNode*)malloc(sizeof(struct ListNode)),*temp4=temp3;
    temp3->val=0;
    temp3->next=NULL;

 int num1=0,num2=0;
 while (temp1!=NULL)
 {
     num1=num1*10 + temp1->val;
    temp1 = temp1->next;
 }

 while (temp2!=NULL)
 {
     num2=num2*10 + temp2->val;
     temp2 = temp2->next;
 }

 int num3 = num1+num2;
 while(num3!=0)
 {
     temp3->val = num3%10;
     temp3->next =  (struct ListNode*)malloc(sizeof(struct ListNode));
     temp3->next->next = NULL;
     temp3 = temp3->next;
     num3/=10;
 }

  return temp4;
}

基本上我已经删除了prev 变量,而不是直接分配NULL。 当数字总和为0 时,您也有大小为struct ListNode 的内存泄漏。我让你弄清楚和处理。

但如果列表中表示的数字更多,最终会溢出整数int num3 = num1+num2;,您的解决方案将不起作用。

最后的任务是将两个列表添加到位,而不是从中提取数字并形成整数。

【讨论】:

  • 我将所有内容都转换为 long long int,但我只清除了 20 个测试用例。 (在我的代码中)
  • 查看我的最后声明。
  • 我知道,正如我所提到的,我尝试了一种蛮力方法来解决这个问题。但是,您的解决方案仅适用于一个测试用例。
  • 我没有给出任何解决方案我刚刚修复了你的错误。
  • 你必须在算法部分工作,否则它会太板而无法在堆栈溢出时回答。
猜你喜欢
  • 2023-02-19
  • 2020-03-26
  • 2022-06-16
  • 2022-06-30
  • 2023-01-24
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
相关资源
最近更新 更多