Во время выполнения моего кода я столкнулся с ошибкой Address Sanitizer - PullRequest
0 голосов
/ 04 июля 2019

Это вопрос из 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;
}


Я применил метод грубой силы и просто добавил два числа. Это дало мне правильное значение. Затем я создаю новый связанный список, где я сохраняю цифру и чтобы компенсировать дополнительный элемент в конце, я сохраняю предыдущий узел в каждом случае. В конце я удаляю связь последнего элемента с дополнительным. Я запускаю свой код и получаю правильный вывод. Я ожидал [7,0,8] и получил [7,0,8]

Вот трассировка:

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

Там действительно не так много, где об ошибке. Это был самый похожий пример, который я мог найти, но я все равно использовал malloc для выделения памяти, а использование free (prev-> next) все испортило. ссылка

Я также хотел бы уточнить, что я не ищу идеального ответа, поскольку я не хочу обманывать, просто выясните, что я делаю неправильно.

Редактировать

Добавление цикла 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; Я решил заменить каждое int на long long int, но это не имеет значения, за исключением очистки пяти дополнительных тестовых случаев. (Я преобразовал каждое значение в long long int, включая константы)

1 Ответ

3 голосов
/ 04 июля 2019

Я внес несколько изменений в указатель без разыменования prev, когда num3 равен 0.

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,Также у вас есть утечка памяти размером struct ListNode, когда сумма чисел 0.Это я позволил вам разобраться и обработать.

Но ваше решение не будет работать, если в списках будет представлено больше цифр, которые в конечном итоге переполнят целые числа int num3 = num1+num2;.

Наконец, задачаэто добавить два списка на месте, чтобы не извлекать из них цифры и образовывать целые числа.

...