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

news2025/1/18 8:29:16

栈和队列报错调试

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.coloradmin.cn/o/1572274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flutter Boost 3

社区的 issue 没有收敛的趋势。 设计过于复杂,概念太多。这让一个新手看 FlutterBoost 的代码很吃力。 这些问题促使我们重新梳理设计,为了彻底解决这些顽固的问题,我们做一次大升级,我们把这次升级命名为 FlutterBoost 3.0&am…

Linux | MySQL安装Workbench图形化

环境:rhel8 MySQL8 下载软件包 官网软件包地址: MySQL :: 下载 MySQL Workbenchhttps://dev.mysql.com/downloads/workbench/我这里下载的是 mysql-workbench-community-8.0.24-1.el8.x86_64.rpm 解决依赖 用rpm安装发现缺少依赖 [rooth…

【游戏分析】逆向数组结构分析

追背包数组 用物品数量当突破口 首先CE扫描目标地址 很简单 找到目标地址 对物品数量地址下写入断,然后吃药 OD中追踪其来源 来源 ecx14 根据堆栈情况 判断此处不是函数头部 但是上面就是retn 那么只能是其他位置跳转而来 在上面发现了跳转来的代码 获得便宜…

ARM架构学习笔记2-汇编

RISC是精简指令集计算机(RISC:Reduced Instruction Set Computing) ARM汇编概述 一开始,ARM公司发布两类指令集: ① ARM指令集,这是32位的,每条指令占据32位,高效,但是太占空间 2…

移位运算与乘法

描述 题目描述: 已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效) 信号示意图: 波形示意图: 输入描述&#…

用于超声图像中的乳腺病变分割的全局指导网络

用于超声图像中的乳腺病变分割的全局指导网络 摘要引言相关工作方法3.1. Global guidance block3.1.1. Spatial-wise global guidance block3.1.2. Channel-wise global guidance block3.2. Breast lesion boundary detection module 3.2.乳腺病灶边界检测模块 Global guidance…

promise.all方式使用

romise.all( ).then( ) 处理多个异步任务,且所有的异步任务都得到结果时的情况。 比如:用户点击按钮,会弹出一个弹出对话框,对话框中有两部分数据呈现,这两部分数据分别是不同的后端接口获取的数据。 弹框弹出后的初…

深入解析消息认证码(MAC)算法:HmacMD5与HmacSHA1

码到三十五 : 个人主页 心中有诗画,指尖舞代码,目光览世界,步履越千山,人间尽值得 ! 目录 引言一、消息认证码(MAC)简介二、HmacMD5算法HmacMD5算法的工作原理 三、HmacSHA1算法HmacSHA1算法的…

什么是SYN攻击,有什么办法防御SYN攻击

自进入数字化互联网时代,网络技术给我们带来了许多服务,为人们的生活增添了许多便利。但同时,网络安全问题也日益凸显,其中DDoS攻击,即分布式拒绝服务攻击,已经成为一种常见的网络威胁。这种攻击方式通过控…

面试经典150题【141-150】

文章目录 面试经典150题【141-150】208.实现前缀树(Trie树)211. 添加与搜索单词-数据结构设计212.单词搜索II200.岛屿数量130.被围绕的区域133.克隆图399.除法求值(未做)拓扑排序207.课程表210.课程表II 面试经典150题【141-150】…

实战:Solrais系统下Oracle 12.2 在线扩容ASM磁盘组操作记录

这篇文章主要是为了记录一下操作,这个假期又要给这套RAC扩容磁盘。 我这套Solaris的小机我还不总操作这玩意,和LINUX有点小差别,整理记录一下,要不每次都是现翻。 存储端划LUN映射到主机 登录到3PAR存储控制台,创建…

ARM汇编与逆向工程:揭秘程序背后的神秘世界

文章目录 一、ARM汇编语言:底层世界的密码二、逆向工程:软件世界的侦探工作三、ARM汇编与逆向工程的完美结合四、ARM汇编逆向工程的风险与挑战五、ARM汇编逆向工程的未来展望《ARM汇编与逆向工程 蓝狐卷 基础知识》内容简介作者简介译者简介ChaMd5安全团…

前端学习之DOM编程案例:抽奖案例

代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>抽奖案例</title><style>*{margin: 0;padding: 0;}</style> </head> <body><div id"container"&g…

【SpringCloud】Nacos 注册中心

目 录 一.认识和安装 Nacos1.Windows安装1. 下载安装包2. 解压3. 端口配置4. 启动5. 访问 2.Linux安装1. 安装JDK2. 上传安装包3. 解压4. 端口配置5. 启动 二.服务注册到 nacos1. 引入依赖2. 配置 nacos 地址3. 重启 三.服务分级存储模型1. 给 user-service 配置集群2. 同集群优…

低代码革新:软件开发的未来潜力与创新路径探索

过去的一年&#xff0c;挑战与机遇并存。人们一边忧虑市场经济下行所带来的新的增长难题、裁员危机&#xff0c;一边惊叹于AIGC、量子技术等领域不断涌现新的创新成果。 时代发生了改变&#xff0c;传统“互联网”的模式已走入尾声&#xff0c;新一轮的科技革命与产业变革正在到…

【刷题】代码随想录算法训练营第三天|203、移除链表元素,707、设计链表,206、反转链表

目录 203. 移除链表元素707. 设计链表206. 反转链表双指针法递归法 203. 移除链表元素 文档讲解&#xff1a;https://programmercarl.com/0203.%E7%A7%BB%E9%99%A4%E9%93%BE%E8%A1%A8%E5%85%83%E7%B4%A0.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV18B4y1s7R9…

活动回顾丨掘金海外,探寻泛娱乐社交APP出海新风口

3月中旬,Flat Ads携手声网、XMP在广州成功举办“泛娱乐社交APP出海新风口——广州站”的主题线下沙龙活动。 多位大咖与泛娱乐社交APP赛道的行业伙伴汇聚一堂。本次活动邀请到Flat Ads 市场VP 王若策、声网娱乐视频产品负责人 陈际陶、XMP资深产品运营专家 屈俊星等多位行业大…

20.安全性测试与评估

每年都会涉及&#xff1b;可能会考大题&#xff1b;多记&#xff01;&#xff01;&#xff01; 典型考点&#xff1a;sql注入、xss&#xff1b; 从2个方面记&#xff1a; 1、测试对象的功能、性能&#xff1b; 2、相关设备的工作原理&#xff1b; 如防火墙&#xff0c;要了解防…

Linux网络管理类命令

ping -c&#xff1a;指定次数 -i n&#xff1a;指定发送频率 n 秒 -t&#xff1a;指定 TTL 值 -s&#xff1a;指定发送包的大小 ifconfig iproute netstat -anltp ss ssh 主机名 SCP wget nmap -A: 全面扫描 -p &#xff1a;端口 80 22-80 80,25,443 -sP &#xf…

机器学习模型——K—Means算法

目录 无监督学习概念&#xff1a; 有监督学习与无监督学习&#xff1a; 无监督学习 - 聚类分析 &#xff1a; 聚类算法应用场景&#xff1a; 常用聚类算法介绍&#xff1a; 对不同的聚类算法应用选择原则&#xff1a; 基于原型聚类&#xff1a; K-Means聚类算法概念及步…