为什么new和malloc输出不同的结果?

时间:2018-01-21 12:05:00

标签: c++ memory-management malloc new-operator

这是我的代码;

#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将导致检测到堆损坏错误。

我想知道为什么会发生这种情况以及与newmalloc有什么不同。

3 个答案:

答案 0 :(得分:3)

n[a] = 0;

此行并进一步使用索引n访问数组a中的元素会导致未定义的行为,这就是程序有时崩溃的原因。

如果您需要处理索引为a的元素,请为此分配足够的内存:

int *n = new int[a + 1];

答案 1 :(得分:2)

n[a] = 0;是未定义的行为。即使您使用malloc,也是未定义的行为。并且合理地停止推理未定义的行为,因为它们是未定义的,并且不依赖于所使用的函数或您可能想到的任何内容。

访问数组索引超出绑定是未定义的行为。

此外,如果您使用scanf正确使用它,则应检查scanf返回的结果,以确定其是否成功。

请注意,您使用newmalloc创建差异行为的想法是错误的。这是udnefined行为的事情之一。它也可以起作用 - 但这并不意味着它每次都能确定地工作。小心。

此外,您可以使用malloc分配必要的内存量。 (当然你也可以用new来做到这一点。)

if( (n=malloc(sizeof(*n)*(a+1)))==NULL){
   perror("malloc");
   exit(EXIT_FAILURE);
}

使用malloc的分配内存只能使用free释放,而new只能delete使用{{1}}。否则就是错误的。

答案 2 :(得分:-3)

newmalloc输出不同的结果,因为一个是C ++,另一个是C.两者的实现完全不同。另请参阅其他答案,告诉您程序有UB。