首页 > 解决方案 > Multiply Strings - [leetcode] 该代码在计算机上运行良好,但在网站上却不行

问题描述

对于 LeetCode 上的“字符串相乘”挑战,我用 C 编写了这段代码;

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

char  *multiply(char *num1, char *num2){
    int num1_len = strlen(num1);
    int num2_len = strlen(num2);
    int *multiplication;

    int total_len = num1_len+num2_len;
    multiplication = (int *)malloc(sizeof(int)*total_len);


    int i, j, k, l;

    for(i = 0; i<total_len; i++){
        multiplication[i] = 0;
    }

    for(i = num1_len-1, k = total_len-1; i>= 0; i--, k--){
        for(j = num2_len-1, l = 0; j>= 0; j--, l++){
            multiplication[k-l] += (num1[i]-48)*(num2[j]-48);
            if(multiplication[k-l]>= 10){
                int number = multiplication[k-l];
                int carry = number%10;
                multiplication[k-l] = carry;
                multiplication[k-l-1] += (number-carry)/10;
            }
        }
    }

    char *multiplication_result;
    multiplication_result = (char *)malloc(sizeof(char));

    int start_index;
    for(i = 0; i<total_len; i++){
        if(multiplication[i] != 0){
            start_index = i;
            break;
        }
    }
    for(i = start_index, j = 0; i<total_len; i++, j++){
        multiplication_result[j] = multiplication[i]+48;
        multiplication_result = (char *)realloc(multiplication_result, j+2);
    }
    return multiplication_result;
}

这在我的电脑上工作得很好。我用不同的字符串对其进行了测试,每个测试都给出了预期的输出。但是,每次我在 leetcode 上运行完全相同的代码时,都会出现运行时错误。它给出了以下错误:

==================================================== =================33==错误:AddressSanitizer:地址 0x602000000092 上的堆缓冲区溢出在 pc 0x55d553422e2b bp 0x7fff8bada4d0 sp 0x7fff8bada4c0 在 0x602000007092 线程 T002fcef01 处读取大小为 1在 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 中,0x602000000092 位于线程 T0 分配的 2 字节区域 [0x602000000090,0x602000000092) 右侧的 0 字节:#0 0x7fcef26f6ffe in __interceptorrealloc /lib/x86_64-linux-gnu/libasan.so.5+0x10dffe) #3 0x7fcef1ab10b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 错误地址周围的影子字节: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 02 fa fa fa 02 fa fa fa 00 fa fa fa fd fa => 0x0c047fff8010:fa fa [02]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
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
0x0c047fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 影子字节图例(一个影子字节代表 8 个应用程序字节):
可寻址:00 部分可寻址:01 02 03 04 05 06 07 堆左redzone:fa 释放的堆区域:fd
堆栈左 redzone:f1 堆栈中 redzone:f2 堆栈右 redzone:f3 返回后堆栈:f5 堆栈使用范围后:f8 全局 redzone:f9 全局初始化顺序:
f6 被用户中毒:f7 容器溢出:fc 数组 cookie:ac Intra object redzone:bb ASan internal:
fe Left alloca redzone:ca Right alloca redzone:cb
Shadow gap:cc ==33==ABORTING

我刚开始对leetcode不太熟悉,也不太擅长阅读这些错误信息。那么是什么导致了这个问题呢?

标签: c

解决方案


您的代码中有(可能)两个问题。第一个(明确的)是您永远不会在字符串中添加nul终止符。要解决此问题,只需在最终循环之后和语句之前multiplication_result添加以下行:forreturn

multiplication_result[j] = '\0';

第二个(可能的)问题——被 clang-cl 编译器标记为警告——是在最终循环start_index开始时变量的值可能未初始化。for要解决这个问题,只需在声明时给它一个初始值 ( 0):

int start_index = 0;

据我所知,第二个问题只有在两个输入字符串都表示零时才会成为问题(但我不想在上面赌任何钱)。


此外,作为可能的改进,以下行:

multiplication[k - l - 1] += (number - carry) / 10;

可以简化为:

multiplication[k - l - 1] += number / 10;

因为整数除法的商将与减去该除法的(潜在)余数i/n执行除法的结果相同(这就是运算符的工作方式)。%


推荐阅读