简体   繁体   English

为什么这 3 行代码会返回 address-sanitizer 错误?

[英]Why does these 3 lines of code return address-sanitizer error?

在此处输入图片说明

int* mostVisited(int n, int* rounds, int roundsSize, int* returnSize){
  
    
    returnSize=malloc(sizeof(int)*100);
    
     printf("%d", roundsSize);
  
    return returnSize;
}

Here you can try the code: https://leetcode.com/contest/weekly-contest-203/problems/most-visited-sector-in-a-circular-track/在这里你可以试试代码: https : //leetcode.com/contest/weekly-contest-203/problems/most-visited-sector-in-a-circular-track/

Edit: Error disappears if i comment the print line.编辑:如果我评论print行,错误就会消失。

This is from a Leetcode challenge, I understand that I am somehow accessing a memory block that is not allocated, that I access something out of the allocated memory Stack.这是来自 Leetcode 的挑战,我知道我以某种方式访问​​了未分配的内存块,我访问了分配的内存堆栈中的某些内容。

The only explanation that I can come up with is that Leetcode's site somehow doesn't allow me to print inside a int function.我能想出的唯一解释是 Leetcode 的网站以某种方式不允许我在int函数中打印。

Error:错误:

=================================================================
==32==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000001d0 at pc 0x000000404edd bp 0x7ffd3d94c7e0 sp 0x7ffd3d94c7d0
READ of size 4 at 0x6140000001d0 thread T0
    #2 0x7f337c09f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
0x6140000001d0 is located 0 bytes to the right of 400-byte region [0x614000000040,0x6140000001d0)
allocated by thread T0 here:
    #0 0x7f337d0baf88 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10bf88)
    #3 0x7f337c09f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
Shadow bytes around the buggy address:
  0x0c287fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff8000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c287fff8010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c287fff8030: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa
  0x0c287fff8040: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c287fff8050: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c287fff8060: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c287fff8070: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c287fff8080: 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
  Shadow gap:              cc
==32==ABORTING

Your code has issues, but not the ones you think.您的代码有问题,但不是您认为的问题。 There can't be an error in the printf : you're passed a value for roundsSize , you print it, period. printf不能有错误:您传递了roundsSize的值, roundsSize打印它,句点。

You're passed returnSize , which is a pointer.你传递了returnSize ,它是一个指针。 You then assign to the local version of returnSize , which doesn't go back to the caller (to do that, you need **returnSize ).然后分配给本地版本的returnSize ,它不会返回给调用者(为此,您需要**returnSize )。 But you then return the new value anyway... what are you actually trying to do?但是无论如何你都会返回新值......你实际上想要做什么?

returnSize is probably already pointing to a good memory location readable by the calling function. returnSize可能已经指向调用函数可读的良好内存位置。 Its purpose is to act as another return value so you can inform the calling function the size of the array that you are returning.它的目的是作为另一个返回值,以便您可以通知调用函数您要返回的数组的大小。 Instead, you are re-assigning (the local version of) it to point to the array that you are also returning.相反,您正在重新分配(本地版本)它以指向您也返回的数组。

The calling function never sees this change to returnSize because the only changes you made to it were localized to the function and didn't modify the data that was stored at the original memory address.调用函数永远不会看到returnSize这种更改,因为您对它所做的唯一更改已本地化到该函数,并且没有修改存储在原始内存地址的数据。 The data at this address is likely garbage as it is expecting your function to give it its value.这个地址的数据可能是垃圾,因为它期望你的函数赋予它它的价值。 If this garbage value happens to be larger than the size of your array, the calling function will likely try to read past the end of the array you allocated.如果此垃圾值恰好大于数组的大小,则调用函数可能会尝试读取您分配的数组末尾。

So the way you should be doing this is probably something along these lines:所以你应该这样做的方式可能是这样的:

int* mostVisited(int n, int* rounds, int roundsSize, int* returnSize){
{
    *returnSize = 100; // or however it is that the size of the array should be determined
    int *ret = malloc(sizeof(*ret) * *returnSize);

    return ret;
}

Of course the rest of the logic for what the function is supposed to do is still up to you to complete.当然,该函数应该做什么的其余逻辑仍然由您来完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM