其实解决问题的方法很简单

news2025/1/25 9:22:30

大家好!我是编码小哥,欢迎关注,持续分享更多实用的编程经验和开发技巧,共同进步! 

本例是一个动态数组的例子,实现数据的增加、删除、根据索引修改数值、获取数值。 

dynamic_array.c

#include "dynamic_array.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

dynamic_array_t *init_dynamic_array()
{
    dynamic_array_t *da = malloc(sizeof(dynamic_array_t));
    da->items = calloc(DEFAULT_CAPACITY, sizeof(void *));
    da->capacity = DEFAULT_CAPACITY;

    return da;
}

void *add(dynamic_array_t *da, const void *value)
{
    if (da->size >= da->capacity)
    {
        void **newItems = realloc(da->items, (da->capacity <<= 1) * sizeof(void **));
        //free(da->items);

        da->items = newItems;
    }

    void *copy_value = retrive_copy_of_value(value);
    da->items[da->size++] = copy_value;

    return copy_value;
}

void *put(dynamic_array_t *da, const void *value, const unsigned index)
{
    if (!contains(da->size, index))
        return INDEX_OUT_OF_BOUNDS;

    free(da->items[index]);
    void *copy_value = retrive_copy_of_value(value);
    da->items[index] = copy_value;

    return copy_value;
}

void *get(dynamic_array_t *da, const unsigned index)
{
    if (!contains(da->size, index))
        return INDEX_OUT_OF_BOUNDS;

    return da->items[index];
}

void delete (dynamic_array_t *da, const unsigned index)
{
    if (!contains(da->size, index))
        return;

    for (unsigned i = index; i < da->size; i++)
    {
        da->items[i] = da->items[i + 1];
    }

    da->size--;

    free(da->items[da->size]);
}

unsigned contains(const unsigned size, const unsigned index)
{
    //printf("size:%d,index:%d\n", size, index);
    if (size >= 0 && index < size)
        return 1;

    printf("index [%d] out of bounds!\n", index);
    return 0;
}

void *retrive_copy_of_value(const void *value)
{
    void *value_copy = malloc(sizeof(void *));
    memcpy(value_copy, value, sizeof(void *));

    return value_copy;
}

 dynamic_array.h

#ifndef __DYNAMIC_ARRAY__
#define __DYNAMIC_ARRAY__
#define DEFAULT_CAPACITY 1 << 4
#define INDEX_OUT_OF_BOUNDS NULL

typedef struct dynamic_array
{
    void **items;
    unsigned size;
    unsigned capacity;
} dynamic_array_t;

extern dynamic_array_t *init_dynamic_array();

extern void *add(dynamic_array_t *da, const void *value);

extern void *put(dynamic_array_t *da, const void *value, unsigned index);

extern void *get(dynamic_array_t *da, const unsigned index);

extern void delete (dynamic_array_t *da, const unsigned index);

unsigned contains(const unsigned size, const unsigned index);

extern void *retrive_copy_of_value(const void *value);

main.c

#include "dynamic_array.h"

int main()
{
    dynamic_array_t *da = init_dynamic_array();

    for (int i = 1; i <= 50; i++)
    {
        add(da, &i);
    }
    
    
    delete (da, 10);
    int value = 999;
    put(da, &value, 0);

    #if 1
    //value = 666;

    int another_value = 666;

    add(da, &another_value);
    #endif

#if 0
    for (int i = 0; i < da->size; i++)
    {
        printf("value[%d]=%d\n",i, *(int *)get(da, i));
    }
#endif

    int value_for_invalid_index = 10000;

    //put(da, &value_for_invalid_index, 150);
    //put(da, &value_for_invalid_index, 65);
    put(da, &value_for_invalid_index, 49);

    for (int i = 0; i < da->size; i++)
    {
        printf("value[%d]=%d\n",i, *(int *)get(da, i));
    }

    free(da->items);
    return 0;
}

 Makefile:

CC = gcc
CFLAGS = -g -Wall

all: main

main: main.o dynamic_array.o
	$(CC) $(CFLAGS) $^ -o $@

dynamic_array.o: dynamic_array.c
	$(CC) $(CFLAGS) -c $^

clean: 
	rm *.o main

 刚开始运行结果是这样的:

f948ecda656440879e5f5cc53ca438b4.png

 于是乎这样调试:

7a6e2ce92b804d57aa96cf8d3d7dae31.png

16915178cf834be1b9bd3bb9421f9944.png

 利用core文件调试:

先设置一下

ulimit -c unlimited

运行一下在当前目录下生成core文件

root@ubuntu-virtual-machine:/home/ubuntu/test# gdb main

gdb结合core文件调试

81464bd4f90448c180d55c57bc3ceb0a.png

代码修正后运行结果:

value[0]=999
value[1]=2
value[2]=3
value[3]=4
value[4]=5
value[5]=6
value[6]=7
value[7]=8
value[8]=9
value[9]=10
value[10]=12
value[11]=13
value[12]=14
value[13]=15
value[14]=16
value[15]=17
value[16]=18
value[17]=19
value[18]=20
value[19]=21
value[20]=22
value[21]=23
value[22]=24
value[23]=25
value[24]=26
value[25]=27
value[26]=28
value[27]=29
value[28]=30
value[29]=31
value[30]=32
value[31]=33
value[32]=34
value[33]=35
value[34]=36
value[35]=37
value[36]=38
value[37]=39
value[38]=40
value[39]=41
value[40]=42
value[41]=43
value[42]=44
value[43]=45
value[44]=46
value[45]=47
value[46]=48
value[47]=49
value[48]=50
value[49]=10000

其实,一开始运行的时候,报错日志就给出了答案,并不需要这么大费周章地调试,debug就像生活一样,有时问题看似很复杂,其实回过头来看一看,答案就在眼前。

 

 

 

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

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

相关文章

redis-stack部署概要

第一步&#xff0c;下载redis-stack 下载链接&#xff1a;Downloads - Redis 第二步&#xff0c;redis安装包解压缩 gzip -d redis-stack-server-7.2.0-v10.rhel8.x86_64.tar.gz tar -xvf redis-stack-server-7.2.0-v10.rhel8.x86_64.tar 第三步&#xff0c;编辑etc下的redis…

centos无法联网解决方案(9步完成

1.打开终端&#xff0c;输入 su - root 进入到管理员模式&#xff08;-的前后都有空格哈&#xff09; 切换后&#xff0c;显示的就是root... 2.. &#xff0c;输入命令ip addr 2. 切换当前目录 cd /etc/sysconfig/network-scripts/ 3.输入命令&#xff0c;打开文件 vi /etc…

【C/C++】设计模式——工厂模式:简单工厂、工厂方法、抽象工厂

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

高通QCS6490开发(四):FV01 AI开发板系统烧录

本期主要介绍如何在FV01开发板上烧录镜像 所用硬件有&#xff1a; FV01开发板和type C线 操作步骤如下&#xff1a; 首先连接电源线开机&#xff0c;然后通过Type C线连接FV01开发板和PC&#xff0c;接线如下&#xff1a; 1&#xff09;将设备通过如下命令进入到EDL紧急下载…

C++ 计时器

文章目录 一、简介二、实现代码2.1 windows平台2.2 C标准库 三、实现效果 一、简介 有时候总是会用到一些计时的操作&#xff0c;这里也整理了一些代码&#xff0c;包括C标准库以及window自带的时间计算函数。 二、实现代码 2.1 windows平台 StopWatch.h #ifndef STOP_WATCH_H…

开源的图形化Windows软件安装升级方案:WingetUI

WingetUI&#xff1a;简化数字生活&#xff0c;WingetUI让软件管理轻松便捷- 精选真开源&#xff0c;释放新价值。 概览 WingetUI是在GitHub上开发的一个实用工具&#xff0c;专为Windows用户设计&#xff0c;旨在为常见的命令行包管理工具&#xff08;如Winget、Scoop、Pip、…

计算机毕业设计hadoop+hive+hbase学情分析 在线教育大数据 课程推荐系统 机器学习 深度学习 人工智能 大数据毕业设计 知识图谱

毕 业 设 计&#xff08;论 文&#xff09;开 题 报 告 1&#xff0e;结合毕业设计&#xff08;论文&#xff09;课题情况&#xff0c;根据所查阅的文献资料&#xff0c;每人撰写不少于1000字的文献综述&#xff1a; 一、研究背景和意义 “互联网”和大数据带来了网络教育的蓬…

API数据对接:本地缓存与日志记录的重要性

关键词&#xff1a;数据治理项目、API接口、数据中心、第三方系统、数据异常、本地缓存、日志记录、数据整合、多源异构数据、数据处理效率 阅读建议&#xff1a; 对于数据治理、API接口和系统集成领域的专业人士&#xff0c;本文深入剖析了本地缓存和日志记录在确保系统稳定性…

信息系统项目管理师0601:项目立项管理 — 考点总结(可直接理解记忆)

点击查看专栏目录 项目立项管理 — 考点总结(可直接理解记忆) 1.项目建议书(又称立项申请)是项目建设单位向上级主管部门提交项目申请时所必须的文件,是对拟建项目提出的框架性的总体设想。在项目建议书批准后,方可开展对外工作(掌握)。 2.项目建议书应该包括的核心内…

系统架构师考试(一)

瀑布模型&#xff08;SDLC&#xff09; 特点&#xff1a; 1、严格区分阶段&#xff0c;每个阶段因果关系紧密相连 2、只适合需求明确的项目 需求分析之后会产出软件需求规格说明书SRS 但是这个模型失败概率到95%&#xff0c;有以下缺陷&#xff1a; 它只适合需求明确的项目…

Spring Boot | Spring Boot 中 自定义“用户退出控制“、获取“登录用户信息“

目录: 一、SpringBoot 中 自定义 "用户授权管理" ( 总体内容介绍 ) :二、 自定义 "用户退出控制" ( 通过 "HttpSecurity类" 的 logout( )方法来实现 "自定义用户用户登录控制" ) :1.基础项目文件准备2.实现 "自定义身份认证"…

Java入门基础学习笔记25——死循环和循环嵌套

死循环&#xff1a; 可以一直执行下去的一种循环&#xff0c;如果没有干预不会停下来。 死循环的写法&#xff1a; 例&#xff1a; package cn.ensource.loop;public class EndLessLoopDemo5 {public static void main(String[] args) {// 目标&#xff1b;掌握死循环的写法w…

GitHub配置SSH协议|什么是SSH

前言 之前用云服务器和GitHub的时候&#xff0c;因为比较懒一直没有配置过ssh。随着最近项目的迫在眉睫&#xff0c;通过Vs Code链接服务器和从GitHub白嫖代码的频率的大幅增加&#xff0c;拒绝接触新事物鼠鼠我只好转求ssh。此篇文章记录了我自己创建ssh密钥、配置ssh密钥的步…

什么是网络端口?为什么会有高危端口?

一、什么是网络端口&#xff1f; 网络技术中的端口默认指的是TCP/IP协议中的服务端口&#xff0c;一共有0-65535个端口&#xff0c;比如我们最常见的端口是80端口默认访问网站的端口就是80&#xff0c;你直接在浏览器打开&#xff0c;会发现浏览器默认把80去掉&#xff0c;就是…

python批量生成防伪识别二维码

欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.代码 三.使用 四.总结 一.前言 二维码(QR Code)是一种矩阵条码技术,它使用黑白矩形图案来表示二进制数据,这些矩形图案可以被设备扫描并解读。二维码可以被用来存储

Spring数据访问全攻略:从JdbcTemplate到声明式事务

上文讲到 —— 航向数据之海&#xff1a;Spring的JPA与Hibernate秘籍 本文目录 四. JdbcTemplate的使用定义JdbcTemplate及其在Spring中的作用展示如何使用JdbcTemplate简化数据库操作1. 配置JdbcTemplate2. 使用JdbcTemplate查询数据3. 打印查询结果 五. Spring的事务管理介绍…

Linux进程(三) --- 状态和优先级

运行&#xff0c;阻塞&#xff0c;挂起 运行 (Running) 当一个进程处于运行状态时&#xff0c;它正在使用CPU执行指令。进程在以下两种情况下可能被认为是运行状态&#xff1a; 实际运行&#xff08;Running on CPU&#xff09;&#xff1a; 进程当前正在CPU上执行。可运行&…

ES6之数值的扩展

1. 数值的扩展 1.1. 二进制和八进制字面量表示:1.2. 数值判断方法: 1.2.1. Number.isFinite() 检查一个值是否为有限的数值。1.2.2. Number.isNaN() 更准确地检测NaN值。1.2.3. 传统的全局方法 isFinite() 和 isNaN() 的区别 1.3. 数值转换方法:1.4. 整数检查与精度: 1.4.1. Nu…

UDP多对多组播通信

广播和多播仅应用于UDP。TCP是一个面向连接的协议&#xff0c;TCP一定是点对点的&#xff0c;一点是两个主机来建立连接的&#xff0c;TCP肯定是单播。只有UDP才会使用广播和组播。 如下示例实现一个UDP多对多的组播通信&#xff0c;进程中有收、发两个线程&#xff0c;分别表…

数字水印 | 奇异值分解 SVD 的定义、原理及性质

目录 1 为什么使用 SVD&#xff1f;2 SVD 的定义是什么&#xff1f;2.1 特征值分解2.2 奇异值分解 3 如何求解奇异值 SV&#xff1f;3.1 求解过程3.2 证明过程 4 什么是 SVD 的性质&#xff1f; 参考博客&#xff1a; Python 机器学习笔记&#xff1a;奇异值分解&…