有关动态内存开辟(new与C库函数malloc等)的一些疑问

舟_井 2024-01-26 02:18:59

 许久没有上社区查看了,翻回到这篇博客,看到了一个比较清晰的对比,与评论区热心朋友们的解答一致,故贴于此处,此贴完结!谢谢大家的耐心解答~

new、delete和malloc、free详解与混用问题 -- 木凡辰

背景:

本次有关图的作业需要存储一个复合数据,由于懒得构造结构体便采取数组,希望构建一个v-d-3的三维数组(v为结点数,d为点的degree,3为三个数据:指向点v、时间开销time与金钱开销cost),然而却遇到了一些问题

问题:

1、问题的出现

当采用new开辟三维数组的第一纬v时

gg=new int** [v];        //开辟v个int**指针

后续calloc函数无法进行,其原因为gg==nullptr(猜测),如下图所示:(为保证看清,图片较大,请谅解!)

 2、问题的探索

希望搞明白出了什么问题(希望完成作业),我开始探索是否其为nullptr,便完全通过new构造了一个三维数组并存入i,再顺序输出,发现完全采用new是可以正常构造出三维数组的,见下图:(此时三维数组可以顺利创建,蓝框仅标记疑问点)

 

 进一步的,通过采用逐步调试的方法、完全使用malloc、calloc等C库函数开辟空间,并查看此时的内存情况,发现此时程序可正常执行完并实现输出,但监视器并不能读取三维数组内的内容,可以肯定的是此时其不为nullptr,见下图:

 但为什么new与malloc等函数不能通用呢?期待大佬们的指点解答,谢谢!

...全文
211 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
初级代码游戏 2024-04-15
  • 打赏
  • 举报
回复 1

你把new和malloc交叉用你们老师不打你吗?new[]返回的内存前面藏了数组长度的,而且,也没人规定new的底层会调用malloc。

舟_井 2024-05-28
  • 举报
回复
@初级代码游戏 这样,谢谢ww
forever74 2024-02-01
  • 打赏
  • 举报
回复

驻阿联酋的比亚迪店面也许因为某种原因替您维修了一辆小鹏。
但是您不能理直气壮地到随便一家比亚迪店要求人家保修你的小鹏。

zara 2024-01-26
  • 打赏
  • 举报
回复 1

刚才在vc2008上试了下,是可以对 new 的空间进行 realloc() 的,内存块被挪移了;代码和运行结果截图如下:

img

#include "stdio.h"
#include "stdlib.h"

int main()
{
    int *p_i = new int [16];
    int *p2, *p3;
    int i;

    p2 = p_i;
    for (i = 0; i < 16; i++)
      *p2++ = i+1;
    p3 = p_i;
    for (i = 0; i < 16; i++)
        printf("%08x:%d\n",p_i, *p_i++);
    p2 = (int *)malloc(16);
    printf("p2=malloc()=%08x\n", p2);
    p2 = (int *)realloc(p2, 256);
    printf("p2=remalloc(256)=%08x\n", p2);
    p_i = (int *)realloc(p3, 512);
    printf("p_i=remalloc(512)=%08x\n", p_i);
    p3 = p_i;
    for (i = 0; i < 16; i++)
        printf("%08x:%d\n",p_i, *p_i++);
    getchar();
    return 0;
} // main()
舟_井 2024-01-26
  • 举报
回复
@zara 好的,谢谢您!我稍晚点好好看看,现在还在外面
初级代码游戏 2024-08-11
  • 举报
回复
@zara 挪移是realloc做的,这没什么问题,问题是原来的内存在new的分配表里面仍是已分配状态,而在malloc的分配表里面属于已回收状态,程序可以继续运行,大概率也不会出BUG——如果这两个内存管理器会做内存整理,问题就会显现
真相重于对错 2024-01-26
  • 打赏
  • 举报
回复 1

c/c++多维数组也是一维连续存储,所以你定义的三维指针没有必要一层一层去malloc。
给你个例子,我这里拿二维数组来举例

typedef int mat[2][2];
int main()
{
   
    
    mat* y=(int (*)[2][2])malloc(sizeof(int)*4);    
     
    *y[1][1]=100;
}


舟_井 2024-01-26
  • 举报
回复
@真相重于对错 好的,谢谢!我再看看理解一下您的写法 但我仍然好奇的是,为什么逐层malloc可以构造、逐层new也可以构造,但new+realloc则会在realloc的时候开辟出错呢?希望得到您进一步的解答,谢谢
zara 2024-01-26
  • 打赏
  • 举报
回复 1

为什么不通用,可能是管理内存的方法不一样吧。
然而此时无法读取内存,106行循环那里,gg这3级是什么内容,整个gg即 n个单元的内容呢?看看108行,到底把new的地址写到了哪里。

舟_井 2024-01-26
  • 举报
回复
@zara gg这个三维数组内容如下:第一维为n个节点,第二维为每个节点的出度,第三维即该节点每条边的信息(连接的点、边的时间开销等) 108行是我试图检查我的new用法有无出错而简单写的代码,可以实现构建三维数组,并且后续realloc可以作用在这三维数组上 很抱歉的是我没有看懂您最后一句的意思,什么是“new到了哪里”?

65,140

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧