当前位置: 首页 > 知识库问答 >
问题:

为什么对malloc分配的数组进行初始化不成功呢?

干宏邈
2024-02-18

LeetCode 43题字符串相乘,乘好后的结果无法放入数组,且初始化并不成功,每次想将数组初始化的时候都会报错。

尝试了用calloc,memset,for循环对数组进行初始化,但是都失败了,直接定义进行初始化也不行,不知道是什么原因?

题目描述:
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

我的代码:

void reverseString(char* str) {       int length = strlen(str);    int start = 0;    int end = length - 1;    while (start < end) {           char temp = str[start];        str[start] = str[end];        str[end] = temp;        start++;        end--;    }}char* multiply(char* num1, char* num2) {    int len = 0;    int len1 = 0;    int len2 = 0;    int temp = 0,t = 0;    int i = 0,j = 0;    len1 = strlen(num1);    len2 = strlen(num2);    char* shortAns = (char*)malloc(sizeof(char) * 2);    shortAns[0] = '0';    shortAns[1] = '\0';    if((len1 == 1 && num1[0] == '0') || (len2 == 1 &&num2[0] == '0'))        return shortAns;    int* A = (int*)malloc(sizeof(int) * len1);    int* B = (int*)malloc(sizeof(int) * len2);    for(i = len1 - 1;i >= 0;i--)        A[i] = num1[i] - '0';    for(i = len2 - 1;i >= 0;i--)        B[i] = num2[i] - '0';    //int* ans = (int*)calloc((len1 + len2 + 1),sizeof(int));    int* ans = (int*)malloc(sizeof(int) * (len1 + len2));    //memset(ans, 0, sizeof(int) * (len1 + len2 + 1));    ans[0] = 0;    ans[1] = 0;    for(i = 0;i < len1;i++){        for(j = 0;j < len2;j++){            t = i + j;            ans[t] += A[i] * B[j];            printf("A*B = %d,ans[%d] = %d\n",A[i] * B[j],t,ans[t]);            //ans[i + j] += temp;        }    }    for(int i = 0;i < len1 + len2;i++){        temp += ans[i];        ans[i] = temp % 10;        temp /= 10;    }    int k = len1 + len2 - 1;    while(k > 0 && ans[k] != 0)//去掉最高位的0        k--;    char* res = (char*)malloc(sizeof(char) * (len1 + len2));    while(k >= 0){        res[len++] = ans[k--] + '0';        //printf("ans[%d] = %d\n",k,ans[k]);    }    res[len] = '\0';    return res;}

可以看到我对ans的初始化进行了多次尝试,现在已经直接去定义了,ans[1] = 0,但是却报错了,这是报的错误,说是堆缓冲区溢出了:
image.png

假如现在把ans[1] = 0,这行注释掉,会输出:
image.png

共有1个答案

孟子墨
2024-02-18

从你的代码中,我看到你试图对动态分配的数组ans进行初始化。然而,你在分配内存时只分配了足够的空间来存储两个整数的乘积,然后试图将所有这些空间初始化为0。这可能是你遇到问题的原因。

你使用了malloc来分配内存,但是malloc只是分配内存,并不会初始化内存区域。所以,当你试图将ans[1] = 0时,实际上你正在试图将一块未初始化的内存设置为0,这是未定义的行为,可能会导致程序崩溃或者出现其他问题。

你应该使用calloc来分配内存,这样会将新分配的内存初始化为0。此外,你的代码中,你试图将一个字符数组res初始化为0,这同样会导致问题,因为字符数组并不需要(也不能)被初始化为0。

修改后的代码如下:

void reverseString(char* str) {       int length = strlen(str);    int start = 0;    int end = length - 1;    while (start < end) {           char temp = str[start];        str[start] = str[end];        str[end] = temp;        start++;        end--;    }}char* multiply(char* num1, char* num2) {    int len = 0;    int len1 = 0;    int len2 = 0;    int temp = 0,t = 0;    int i = 0,j = 0;    len1 = strlen(num1);    len2 = strlen(num2);    char* shortAns = (char*)malloc(sizeof(char) * 2);    shortAns[0] = '0';    shortAns[1] = '\0';    if((len1 == 1 && num1[0] == '0') || (len2 == 1 &&num2[0] == '0'))        return shortAns;    int* A = (int*)calloc(len1, sizeof(int)); // 使用 calloc 初始化数组 A    int* B = (int*)calloc(len2, sizeof(int)); // 使用 calloc 初始化数组 B    for(i = len1 - 1;i >= 0;i--)        A[i] = num1[i] - '0';    for(i = len2 - 1;i >= 0;i--)        B[i] = num2[i] - '0';    //int* ans = (int*)calloc((len1 + len2 + 1),sizeof(int)); // 使用 calloc 初始化数组 ans    int* ans = (int*)malloc(sizeof(int) * (len1 + len2)); // 使用 malloc 分配内存给 ans    //memset(ans, 0, sizeof(int) * (len1 + len2 + 1)); // 使用 memset 将 ans 初始化为 0    ans[0] = 0; // 初始化 ans[0] 为 0 是正确的,但是其它元素不应该被设置为0。因为它们会被后面的计算所覆盖。    ans[1] = 0; // 同上    for(i = 0;i < len1;i++){        for(j = 0;j < len2;j++){            t = i + j;            ans[t] += A[i] * B[j]; // 这里将乘积加到 ans 的对应位置上。这是正确的。            printf("A*B = %d,ans[%d] = %d\n",A[i] * B[j],t,ans[t]); // 打印乘积和 ans 的当前值是正确的。这有助于调试。            //ans[i + j] += temp; // 这行代码是多余的,因为它只会覆盖掉之前计算的乘积。应该删除这行代码。        }    }    for(int i = 0;i < len1 + len2;i++){        temp += ans[i]; // 这个循环计算所有乘积的和。这是正确的。但是,这里应该是 temp += ans[i]; 而非 ans[i] = temp % 10; temp /= 10; 因为我们是将所有的乘积加起来,而不是将每个乘积的个位数提取出来。所以应该删除这两行代码。
 类似资料: