这是我的代码;
#include <cstdio>
#include <cstdlib>
using namespace std;
int MIN(int a, int b)
{
if (a <= b) return a;
else return b;
}
int main(void)
{
int a;
scanf("%d", &a);
int *n = new int[a];
//int *n = (int *)malloc(sizeof(int)*(a));
for (int i = 0; i < a; i++)
n[i] = a;
n[a] = 0;
for (int i = a; i > 1; i--)
{
if (i % 3 == 0) n[i / 3] = MIN(n[i] + 1, n[i / 3]);
else if (i % 2 == 0) n[i / 2] = MIN(n[i] + 1, n[i / 2]);
n[i - 1] = MIN(n[i] + 1, n[i - 1]);
}
printf("%d", n[1]);
delete[] n;
//free(n);
return 0;
}
如果您使用new
,则不会发生任何事情。
但是,使用malloc
将导致检测到堆损坏错误。
我想知道为什么会发生这种情况以及与new
和malloc
有什么不同。
答案 0 :(得分:3)
n[a] = 0;
此行并进一步使用索引n
访问数组a
中的元素会导致未定义的行为,这就是程序有时崩溃的原因。
如果您需要处理索引为a
的元素,请为此分配足够的内存:
int *n = new int[a + 1];
答案 1 :(得分:2)
n[a] = 0;
是未定义的行为。即使您使用malloc
,也是未定义的行为。并且合理地停止推理未定义的行为,因为它们是未定义的,并且不依赖于所使用的函数或您可能想到的任何内容。
访问数组索引超出绑定是未定义的行为。
此外,如果您使用scanf
正确使用它,则应检查scanf
返回的结果,以确定其是否成功。
请注意,您使用new
和malloc
创建差异行为的想法是错误的。这是udnefined行为的事情之一。它也可以起作用 - 但这并不意味着它每次都能确定地工作。小心。
此外,您可以使用malloc
分配必要的内存量。 (当然你也可以用new
来做到这一点。)
if( (n=malloc(sizeof(*n)*(a+1)))==NULL){
perror("malloc");
exit(EXIT_FAILURE);
}
使用malloc
的分配内存只能使用free
释放,而new
只能delete
使用{{1}}。否则就是错误的。
答案 2 :(得分:-3)
new
和malloc
输出不同的结果,因为一个是C ++,另一个是C.两者的实现完全不同。另请参阅其他答案,告诉您程序有UB。