为什么new和malloc输出的结果不一样?
Why does new and malloc output different results?
这是我的代码;
#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
有何不同。
n[a] = 0;
此行并进一步访问数组 n
中索引为 a
的元素会导致未定义的行为,这就是程序有时会崩溃的原因。
如果您需要处理索引为 a
的元素,请为此分配足够的内存:
int *n = new int[a + 1];
n[a] = 0;
是未定义的行为。即使您使用 malloc
也是未定义的行为。停止推理未定义的行为是合乎逻辑的,因为它们是未定义的并且不依赖于所使用的函数或您可能想到的任何东西。
越界访问数组索引是未定义的行为。
此外,如果您正在使用 scanf
,请正确使用它 - 应检查 scanf
returns 的结果以了解其是否成功。
请注意,您认为使用 new
和 malloc
会产生差异行为的想法是错误的。这是具有未定义行为的事情之一。它也可能有效——但这并不意味着它每次都会有效。小心。
您也可以使用 malloc
分配必要的内存量。 (当然你也可以用 new
做到这一点)。
if( (n=malloc(sizeof(*n)*(a+1)))==NULL){
perror("malloc");
exit(EXIT_FAILURE);
}
使用 malloc
分配的内存只能使用 free
释放,对于 new
则为 delete
。否则出错。
new
和 malloc
输出不同的结果,因为一个是 C++,另一个是 C。两者的实现完全不同。另请参阅告诉您您的程序有 UB 的其他答案。
这是我的代码;
#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
有何不同。
n[a] = 0;
此行并进一步访问数组 n
中索引为 a
的元素会导致未定义的行为,这就是程序有时会崩溃的原因。
如果您需要处理索引为 a
的元素,请为此分配足够的内存:
int *n = new int[a + 1];
n[a] = 0;
是未定义的行为。即使您使用 malloc
也是未定义的行为。停止推理未定义的行为是合乎逻辑的,因为它们是未定义的并且不依赖于所使用的函数或您可能想到的任何东西。
越界访问数组索引是未定义的行为。
此外,如果您正在使用 scanf
,请正确使用它 - 应检查 scanf
returns 的结果以了解其是否成功。
请注意,您认为使用 new
和 malloc
会产生差异行为的想法是错误的。这是具有未定义行为的事情之一。它也可能有效——但这并不意味着它每次都会有效。小心。
您也可以使用 malloc
分配必要的内存量。 (当然你也可以用 new
做到这一点)。
if( (n=malloc(sizeof(*n)*(a+1)))==NULL){
perror("malloc");
exit(EXIT_FAILURE);
}
使用 malloc
分配的内存只能使用 free
释放,对于 new
则为 delete
。否则出错。
new
和 malloc
输出不同的结果,因为一个是 C++,另一个是 C。两者的实现完全不同。另请参阅告诉您您的程序有 UB 的其他答案。