Конкатенация двух массивов int с использованием memcpy - PullRequest
0 голосов
/ 05 марта 2019

Это может занять много времени, но, по сути, я пытаюсь объединить два массива int: [1,2] и [3,4], чтобы получить результат [1,2,3,4].

Мой код - мой предложенныйРешение этой проблемы leetcode .

Вот мой код:

#include <stdio.h>

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
    int totalLen = nums1Size + nums2Size;
    int halflen = totalLen/2;
    int INTSIZE = sizeof(int);
    int* arr = malloc(INTSIZE*totalLen);
    int c1 = 0;
    int c2 = 0;

    // loop through lists to combine them into a sorted array
    for (int i = 0; i < halflen+1; i++) {
        if (nums1[c1] > nums2[c2]) {
            arr[i] = nums2[c2];
            c2++;
        } else {
            arr[i] = nums1[c1];
            c1++;
        }

        // PART THAT BREAKS
        // If we've exhausted all of nums1, concat nums2 to the end of it
        if (c1 >= nums1Size) {
            memcpy(arr+(i*INTSIZE), nums2, INTSIZE*(nums2Size-c2)); 
            break;
        }
    }

    // find and return median
    if ((int)halflen < halflen) {
        return (arr[halflen] + arr[halflen-1]) / 2;
    } else {
        return arr[halflen];
    }
}

Может кто-нибудь объяснить, что я делаю неправильно, и как это исправить?Ошибка, с которой я столкнулся:

================================================================= 
==30==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000070 at pc 0x7fbe96801784 bp 0x7ffff6c07570 sp 0x7ffff6c06d20 
WRITE of size 8 at 0x602000000070 thread T0 
    #0 0x7fbe96801783 (/usr/local/lib64/libasan.so.5+0x3e783) 
    #4 0x7fbe954212e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0) 

Address 0x602000000070 is a wild pointer. 
SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/local/lib64/libasan.so.5+0x3e783) 
Shadow bytes around the buggy address: 
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
=>0x0c047fff8000: fa fa 00 fa fa fa 00 fa fa fa 00 00 fa fa[fa]fa 
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
Shadow byte legend (one shadow byte represents 8 application bytes): 
Addressable: 00 
Partially addressable: 01 02 03 04 05 06 07 
Heap left redzone: fa 
Freed heap region: fd 
Stack left redzone: f1 
Stack mid redzone: f2 
Stack right redzone: f3 
Stack after return: f5 
Stack use after scope: f8 
Global redzone: f9 
Global init order: f6 
Poisoned by user: f7 
Container overflow: fc 
Array cookie: ac 
Intra object redzone: bb 
ASan internal: fe 
Left alloca redzone: ca Right alloca redzone: cb 
==30==ABORTING

(я также понятия не имею, что большая часть этой ошибки пытается сказать мне, к сожалению)

1 Ответ

0 голосов
/ 05 марта 2019

Вы неправильно вычисляете свои адреса в memcpy.Поскольку arr как int *, вы добавляете число целых чисел для перемещения указателя, а не количество байтов.

Один из способов исправить это - просто позволитькомпилятор вычисляет адреса:

memcpy(&arr[i], &nums2[c2], INTSIZE*(nums2Size-c2));

Или, придерживаясь указателя математики,

memcpy(arr + i, nums2 + c2, INTSIZE*(nums2Size-c2));

Последний параметр - это количество байтов для копирования, поэтому необходимо подсчитать целое числобыть преобразован в число байтов.

В обоих случаях я настроил второй параметр, чтобы начать копирование из правильного элемента в массиве nums2.

Затем спросите себя: чтопроизойдет, если c2 достигнет nums2Size?Вы в настоящее время не рассматриваете это дело.

...