c++ - 找出一个意外数字的 K-Beauty Runtime Error

我最近在 Leetcode Biweekly Competition 78 中做第一个问题,我收到了一个我无法理解的意外 runtime error ,特别是因为我之前写过类似的代码,它运行良好。我对编程和这些比赛很陌生,请告诉我这个 Runtime Error 是什么意思以及如何更改我的代码来修复它。

class Solution {
public:
    int divisorSubstrings(int num, int k) {
        string b=to_string(num);
        string a="";
        int x;
        int ans=0;
        for(int i=0;i<=b.size()-k;++i){
            for(int j=i;i<i+k;++j){
                a+=b[j];
            }
            x=stoi(a);
            if(num%x==0){
                ++ans;
            }
        }
        
        return ans;
    }
};

和错误:

=================================================================
==33==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffca3ed0900 at pc 0x000000343d81 bp 0x7ffca3ed0890 sp 0x7ffca3ed0888
READ of size 1 at 0x7ffca3ed0900 thread T0
    #2 0x7fe89b85d0b2  (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
Address 0x7ffca3ed0900 is located in stack of thread T0 at offset 96 in frame
  This frame has 4 object(s):
    [32, 40) '__endptr.i'
    [64, 96) 'b' <== Memory access at offset 96 overflows this variable
    [128, 160) 'a'
    [192, 193) 'ref.tmp'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
Shadow bytes around the buggy address:
  0x1000147d20d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000147d20e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000147d20f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000147d2100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000147d2110: 00 00 00 00 f1 f1 f1 f1 f8 f2 f2 f2 00 00 00 00
=>0x1000147d2120:[f2]f2 f2 f2 00 00 00 00 f2 f2 f2 f2 f8 f3 f3 f3
  0x1000147d2130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000147d2140: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
  0x1000147d2150: 01 f2 04 f2 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000147d2160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000147d2170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==33==ABORTING

如果您需要这个问题,请访问 https://leetcode.com/contest/biweekly-contest-78/problems/find-the-k-beauty-of-a-number/

谢谢

回答1

你的问题是这行代码:

for(int j=i;i<i+k;++j){

你有两个习惯应该改掉。首先,您不使用空格。这使得这一行中的错误更难阅读。其次,您使用非常短的变量名。这也使这一行中的错误更难阅读。

那个for循环永远循环。问题是中心子句:

i < i + k

注意当我添加空格时它有多明显?随着年龄的增长和眼睛的老化,这个问题会变得更糟。代码开始像一堵无法阅读的文本墙。像我这样的老屁将无法阅读您的代码。

所以,请添加一点空白。我会这样写那行:

for (int j = i; j < i + k; ++j) {

是的,它需要更多的水平空间。空间很便宜。虫子很贵。

请注意,我仍然认为此代码将超出 b 的大小范围,因此您可能仍然会遇到问题。

回答2

这是从您的代码段修改的公认解决方案。查看所做的更改。

class Solution {
public:
    int divisorSubstrings(int num, int k) {
        
        string b = to_string(num);
        int ans = 0;
        
        for(int i = 0; i <= b.size() - k; i++) { // the error causing crash 
            string a = ""; // keep declation close to it's usage, compiler will optimize declaration
            for(int j = i; j < i + k; j++)  a += b[j];
            int x = stoi(a);
            if (!x) continue; // you might not want to devide by 0
            if( num % x == 0 ) ans++;
        }
        
        return ans;
    }
};

相似文章

随机推荐

最新文章