路人甲的帮助——C指针的指针引发的错误

简介:   早20多天,有网名为chaozhisong的同学给我来信,问下面的程序为什么会出现段错误?#include<stdio.h>void test4(void** a){ int i,j; for(i=0; i<3; i++) { for(j=0; j<3; j++) printf("%d\n",(

  早20多天,有网名为chaozhisong的同学给我来信,问下面的程序为什么会出现段错误?

#include<stdio.h>
void test4(void** a)
{
    int i,j;
    for(i=0; i<3; i++)
    {
        for(j=0; j<3; j++)
            printf("%d\n",((int**)a)[0][j]);
    }
}
int main()
{
    int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
    test4(arr);
    return 0;
}

  那几天挺忙的,等抽出时间看已经晚了,而程序里面指针绕来绕去的,搞了十多分钟,还有其他事等着,我不得不放弃了。

  我回复道:“我也没有时间继续找个正解了。通过论坛,求一下解释吧,那里有经验更丰富的高手。如果方便,届时告我一下结果。”

  其实,遇到程序中存在的问题时,找论坛是最快的,能看到的人也多,这个方式可以有。

  这样回复完后,我也已经有些忘记了。

  现在却收到了luochengguo的私信。他作出了解答,私信主题是“路人甲问题解答”。真好,好人万岁。

  下面就是路人甲的解答。
--------------------------------------------------------
  贺老师您好以及chaozhisong这位同学你好,刚刚恰巧逛贺老师论坛看到了这位同学的问题,我大概说一下,不对的请两位见谅:
  1. 首先我对这位同学的代码的目的有点模糊 , 基本应该觉得这位同学是想完整遍历这个二维数组,但是从代码实际情况看即使没有发生段错误也只能重复三次遍历并打印这个二维数组的第一行。
  2. 基础知识: 关于二维数组的遍历,一般以下三种方法都可以:
  a. void out(int *p, int n);
  b. void out(int *p, int row, int col);
  c. void out(int p[][4], int row); //等价于void out(int (×p)[4], int row);
  其实上面这三种方法你都能理解和实现,就看你对一维数组和二维数组的理解,包括二维数组本质就是多个一维数组的一维数组,以及你对指针和数组名的区别,包括一维数组名和二维数组名的实际意义,包括数组指针等这里一系列有关系内容的本质的理解和梳理了, 由于一一例出比较多,我就不多说了(如果这位同学对这些知识点比较模糊或
不能说出所有然,说明基础不扎实)。
  3. 如果第2点中的内容你真的全部理解和融汇贯通了, 其实这个问题你要有个正解应该没有任何问题
  4. 继续回到你的实际问题,如果你确实想遍历这个二维数组的第一行3遍,那就将错就错, 把你的代码改成没有段错误并能顺利遍历出来, 最小的改动可以如下:

void show(void **array)
{
    int i;
    int j;
    int (*a)[3] = array;
    for(i=0; i < 3; i++)
    {
        for(j=0; j < 3; j++)
        {
            printf("%d\n",a[0][j]);
        }
    }
}
  如果你本来是想遍历整个二维数组,那么改的方式就太多了,以下随意例出几种:
  方式一:
void show(void**array)
{
    int i;
    int j;
//    for(i=0; i < 3; i++)
//    {
        for(j=0; j < 9; j++)
        {
            printf("%d\n", ((int*)array)[j]);
        }
//    }
}
  方式二:
void show(int array[][3]) //或void show(int (*array)[3])当然一般其实还有第二个参数就是行数n
{
    int i;
    int j;
    for(i=0; i < 3; i++)
    {
        for(j=0; j < 3; j++)
        {
            printf("%d\n", array[i][j]);
        }
    }
}
  等等 其他各种改法, 主要就还是看你对第2点的理解了。
  5. 再次回到你实际问题,包括从上面的修改你也可以看出, 可能这位同学的问题还是出在基础知识不扎实,对数组和指针的异同理解不到位... 就从最基础的代码层面来讲,主要问题就出在((int**)a)[0][j])这里, 在对数组元素访问的之前其实此时a根本就已经不是一个数组名了, 被强转成了一个普通的二级指针, 一个普通的二级指针哪来的行和列,这个指针名字a在编译器看来已经失去了数组的意义了, 更没有了行和列的意义。对于这个普通的局部变量二级指针a, 根本就不知道要访问那块内存,当然段错误了(类似于你申明一个指针,却没有任何指向,然后去解引用操作(大概就这个意思),当然段错误)。
  什么各种内存图就不画了。。。。
  以上所有仅个人想法, 觉得不对请见谅。 只做基本的参考

----------------

  感谢路人甲的分享!




==================== 迂者 贺利坚 CSDN博客专栏=================
|== IT学子成长指导专栏 专栏文章的分类目录(不定期更新) ==|
|== C++ 课堂在线专栏  贺利坚课程教学链接(分课程年级) ==|
|== 我写的书——《逆袭大学——传给IT学子的正能量》    ==|
===== 为IT菜鸟起飞铺跑道,和学生一起享受快乐和激情的大学 =====




目录
相关文章
|
9天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
8天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
373 130
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
8天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
366 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
|
20天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1342 8
|
2天前
|
存储 JSON 安全
加密和解密函数的具体实现代码
加密和解密函数的具体实现代码
193 136
|
7天前
|
监控 JavaScript Java
基于大模型技术的反欺诈知识问答系统
随着互联网与金融科技发展,网络欺诈频发,构建高效反欺诈平台成为迫切需求。本文基于Java、Vue.js、Spring Boot与MySQL技术,设计实现集欺诈识别、宣传教育、用户互动于一体的反欺诈系统,提升公众防范意识,助力企业合规与用户权益保护。
|
19天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1443 87
|
7天前
|
JavaScript Java 大数据
基于JavaWeb的销售管理系统设计系统
本系统基于Java、MySQL、Spring Boot与Vue.js技术,构建高效、可扩展的销售管理平台,实现客户、订单、数据可视化等全流程自动化管理,提升企业运营效率与决策能力。