数据结构面试题报错调试方法记录

栈和队列报错调试

1.用栈实现队列

232. 用栈实现队列 - 力扣(LeetCode)

此题解题思路如下:

先将数据放在pushst栈里面,popst栈为空再把pushst栈里面的数据放进popst栈里面去,不为空则不执行。不为空时候直接拿取栈顶数据。

GIF 2024-4-2 19-14-14

代码如下:

typedef int STDataType;typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;void STInit(ST* pst);
void STDestroy(ST* pst);void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);//拿取栈顶数据bool STEmpty(ST* pst);
int STSize(ST* pst);void STInit(ST* pst)
{assert(pst);pst->a = NULL;pst->capacity = 0;//表示top指向栈顶元素的下一个位置pst->top = 0;
}void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->capacity = pst->top = 0;
}void STPush(ST* pst, STDataType x)
{assert(pst);if (pst->top == pst->capacity){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);if (tmp == NULL){perror("realloc fail");return;}pst->a = tmp;pst->capacity = newcapacity;}pst->a[pst->top] = x;pst->top++;
}void STPop(ST* pst)
{assert(pst);assert(pst->top >0);pst->top--;
}STDataType STTop(ST* pst)
{assert(pst);assert(pst->top > 0);return pst->a[pst->top-1];
}bool STEmpty(ST* pst)//判断真假
{assert(pst);return pst->top == 0;
}int STSize(ST* pst)
{assert(pst);return pst->top;
}typedef struct 
{ST pushst;ST popst;
} MyQueue;MyQueue* myQueueCreate() 
{MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->pushst);STInit(&obj->popst);return obj;
}void myQueuePush(MyQueue* obj, int x) 
{STPush(&obj->pushst, x);
}int myQueuePop(MyQueue* obj) 
{int tmp=myQueuePeek(&obj->popst);STPop(&obj->popst);return tmp;
}int myQueuePeek(MyQueue* obj) 
{if(STEmpty(&obj->popst)){while(!STEmpty(&obj->pushst)){STPush(&obj->popst, STTop(&obj->pushst));STPop(&obj->pushst);}}return STTop(&obj->popst);
}bool myQueueEmpty(MyQueue* obj) 
{return STEmpty(&obj->pushst)&&STEmpty(&obj->popst);
}void myQueueFree(MyQueue* obj) 
{STDestroy(&obj->popst);STDestroy(&obj->pushst);free(obj);obj =NULL;
}/*** Your MyQueue struct will be instantiated and called as such:* MyQueue* obj = myQueueCreate();* myQueuePush(obj, x);* int param_2 = myQueuePop(obj);* int param_3 = myQueuePeek(obj);* bool param_4 = myQueueEmpty(obj);* myQueueFree(obj);
*/

报错1如下:

image-20240402095239891

错误原因分析:

编译出错是运行问题,执行出错是代码逻辑问题,没有报结果大概率是头部出错。以此为基础推导出错原因,思路如下:

将上面代码拷贝至VS调试按照力扣所提供的测试样例进行传参,这道题我是使用栈实现代码进行解题,所以直接使用之前的实现代码进行调试,如果不知道栈的实现方法请观看这篇文章:

我们观察力扣所提供的测试样例:

image-20240402100810433

我们先看力扣对这几个函数的传参设置:

image-20240402101850053

函数"MyQueue"无传参值设置只需要一个返回值接受它,所以无需传参。调用两次"push"函数传结构体指针然后分别给x传1,2。剩下的"peek",“pop”,"empty"只需要传结构体指针。

但一般调试无需调用这么多函数,我调用了两个函数进行调试,调用如下:

int main()
{MyQueue* obj = myQueueCreate();myQueuePush(&obj, 1);return 0;
}

运行时候realloc函数会报错,出现内存不足的问题:

image-20240402103447110

首先排除栈实现代码问题,因为实现时候调试过,没有报错,我们将问题范围缩小在实现队列部分,而初始化问题我前面已经解决了,那么排除初始化问题。因为是开辟空间报错,我们监视栈的结构体值变化,如图所示发现运行STPush函数的时候,栈的结构体里面的指针会变成野指针:

image-20240402160928254

我们查看所有调用STPush的函数:

image-20240402160138241

按思路走读一下代码,发现myQueuePop函数调用myQueuePeek函数时候我们想传的是出栈函数的地址给myQueuePeek函数进行调用,myQueuePeek函数调用STPush的函数我们想传的是出栈函数的地址给STPush函数进行调用,我们将此代码的思路图画出来,发现obj访问pushst结构体后再访问里面的pushst结构体,所以是传参错误,因为myQueuePeek函数里面已经传pushst的地址给STPush函数了,所以myQueuePop函数调用myQueuePeek函数只需要传obj指针调用即可。

image-20240402163030998

报错2如下:

image-20240402193810781

实现代码如下:

typedef struct 
{ST* pushst;ST* popst;
} MyQueue;MyQueue* myQueueCreate() 
{MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->pushst);STInit(&obj->popst);return obj;
}void myQueuePush(MyQueue* obj, int x) 
{STPush(&obj->pushst, x);
}int myQueuePop(MyQueue* obj) 
{int tmp=myQueuePeek(obj);STPop(&obj->popst);return tmp;
}int myQueuePeek(MyQueue* obj) 
{if(STEmpty(&obj->popst)){while(!STEmpty(&obj->pushst)){STPush(&obj->popst, STTop(&obj->pushst));STPop(&obj->pushst);}}return STTop(&obj->popst);
}bool myQueueEmpty(MyQueue* obj) 
{return STEmpty(&obj->pushst)&&STEmpty(&obj->popst);
}void myQueueFree(MyQueue* obj) 
{STDestroy(&obj->popst);STDestroy(&obj->pushst);free(obj);obj =NULL;
}

我们观察这段代码:

image-20240402194929377

malloc函数开辟出来的指针只为MyQueue结构体开辟空间。但是MyQueue结构体里存放了两个结构体指针,不初始化就为空指针,初始化了为空指针,在栈实现的代码中assert(pst)会报错。不初始化会出现野指针访问报错,如果要写两个指针,需要再为这两个指针开辟空间。
STDestroy(&obj->popst);
STDestroy(&obj->pushst);

free(obj);
obj =NULL;

}


我们观察这段代码:[外链图片转存中...(img-RbuGxtYJ-1712389444934)]malloc函数开辟出来的指针只为MyQueue结构体开辟空间。但是MyQueue结构体里存放了两个结构体指针,不初始化就为空指针,初始化了为空指针,在栈实现的代码中assert(pst)会报错。不初始化会出现野指针访问报错,如果要写两个指针,需要再为这两个指针开辟空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/598209.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

测试框架pytest学习与实践

pytest是一个专业的测试框架,可以帮助我们对python项目进行测试,提高测试的效率。 pytest官网手册:pytest: helps you write better programs — pytest documentation 中文手册:Pytest 教程 入门学习 安装pytest pip install…

机器人开启私聊配置自定义接口的方式

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂。 今天给大家介绍一下,如何在机器人中开启私聊回复。 前提条件:机器人已经启动好了,且功能也都可以正常使用,如果没有启动,可以联…

《QT实用小工具·十八》高亮发光按钮控件

1、概述 源码放在文章末尾 该项目实现了高亮发光按钮控件 可设置文本,居中显示。可设置文本颜色。可设置外边框渐变颜色。可设置里边框渐变颜色。可设置背景色。可直接调用内置的设置 绿色、红色、黄色、黑色、蓝色 等公有槽函数。可设置是否在容器中可移动&#…

生成式AI产品汇总网站

在 AIHungry.com,我们处于人工智能发展的最前沿,为您带来最新的人工智能。深入了解我们对最佳人工智能工具的全面评论,并随时了解我们对人工智能新闻的报道。 人工智能新闻:随时了解人工智能领域的最新发展和突破。工具评论&…

国内估值最高的大模型公司,“国产大模型五虎”系列之——智谱AI

前言: 上次我们介绍了同为“国产大模型五虎”的MiniMax,今天就继续来盘点一下国内估值最高的大模型企业智谱AI,同时也是五虎中的另外一虎。 “国产大模型五虎”指的是由阿里投资的五家大模型独角兽:智谱 AI、百川智能、月之暗面…

人工智能大模型+智能算力,企商在线以新质生产力赋能数字化转型

2024 年3月28 日,由中国互联网协会主办、中国信通院泰尔终端实验室特别支持的 2024 高质量数字化转型创新发展大会暨铸基计划年度会议在京召开。作为新质生产力代表性企业、数算融合领导企业,企商在线受邀出席大会主论坛圆桌对话,与行业专家共…

C++初级----string类(STL)

1、标准库中的string 1.1、sring介绍 字符串是表示字符序列的类,标准的字符串类提供了对此类对象的支,其接口类似于标准字符容器的接口,但是添加了专门用于操作的单字节字符字符串的设计特性。 string类是使用char,即作为他的字符…

【蓝桥杯嵌入式】12届程序题刷题记录及反思

一、题目解析 按键短按LCD显示两个界面LED指示灯PWM脉冲输出 二、led控制 控制两个led灯&#xff0c;两种状态 //led void led_set(uint8_t led_dis) {HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC,led_dis << 8,GPIO_PIN_RESET);HAL…

高度不同的流体瀑布css实现方法

商城商品列表 实现瀑布流展示&#xff0c;通过flex或grid实现会导致每行中的列高度一致&#xff0c;无法达到错落有致的感觉&#xff1b; 为此需要用到&#xff1a; CSS columns 属性 columns 属性是一个简写属性&#xff0c;用于设置列宽和列数。 CSS 语法 columns: column-wi…

一些增强生产力的 AI 工具

engshell 支持自然语言交互的 shell engshell 是一个适用于任何操作系统的英语 shell&#xff0c;由 LLM 提供自然语言交互支持 Paints Chainer 漫画线稿上色 AI Paints Chainer 是一款用于为漫画上色的工具&#xff0c;只需上传一张黑白线稿&#xff0c;点击按钮&#xff0…

JQuery(二)---【使用JQuery对HTML、CSS进行操作】

零.前言 JQuery(一)---【JQuery简介、安装、初步使用、各种事件】-CSDN博客 一.使用JQuery对HTML操作 1.1获取元素内容、属性 使用JQ可以操作元素的“内容” text()&#xff1a;设置或返回元素的文本内容html()&#xff1a;设置或返回元素的内容(包括HTML标记)val()&#…

Leetcode 102. 二叉树的层序遍历

注意的点&#xff1a; 1、队列注意用popleft 2、注意用len(queue)控制层数 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right righ…