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,但是却报错了,这是报的错误,说是堆缓冲区溢出了:
假如现在把ans[1] = 0,这行注释掉,会输出:
从你的代码中,我看到你试图对动态分配的数组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; 因为我们是将所有的乘积加起来,而不是将每个乘积的个位数提取出来。所以应该删除这两行代码。
问题内容: 我希望您能从该示例中了解到我想要做什么。我该如何在Go中执行此操作? 问题答案: (点击播放)
问题内容: 平台之间可能有所不同,但是 当我使用gcc编译并运行下面的代码时,每次在ubuntu 11.10中获得0。 为什么即使有calloc,malloc的行为也是如此? 难道就意味着即使您不希望有时将值初始化为0,也会有不必要的性能开销吗? 编辑:哦,我以前的示例不是初始化,而是碰巧使用“新鲜”块。 我恰恰在寻找的是为什么它在分配一个大块时将其初始化: 但是,感谢您指出进行分配时存在安全原因
我想从字符串数组初始化一个对象数组。 在这些日志之后我没有任何东西,也没有找到应用程序崩溃的任何原因。
为什么在这种情况下两个数组的作用不同?
我想存储一组/值,但是s不一定是增量的,这意味着数据可以是: 因此,我试图创建一个c#等价的