【C language】动态数组的创建和使用

在C语言中,使用malloc函数创建动态数组,使用一个指针指向它,使用下标进行访问。

unsigned long *a = (unsigned long *)malloc(2 * sizeof(int));
a[0] = 1000;
a[1] = 2000;
printf("%d  %d\n", a[0], a[1]);
free(a);

上述例子,申请了两个int空间的动态数组,使用int *指向它,使用a[0],a[1]访问,这与数组访问一样,区别就是动态申请内存在堆空间,还需要使用free进行释放,而一般的数组在栈空间,自动释放。

这个很容易,这里想延申类比一下,这是Liunx 0.11内核类似的一段代码很有趣。

#include <stdio.h>
#include <stdlib.h>typedef struct desc_struct
{		                		unsigned long a, b;		
} 
desc_table[256];desc_table idt, gdt;void set_gate(unsigned long *gate_addr) {gate_addr[0] = 100;gate_addr[1] = 200;
}int main() {int size = sizeof(idt) / sizeof(idt[0]); // size = 256printf("%d\n",size);printf("%d  %d\n", idt[0].a, idt[0].b);set_gate((unsigned long *)&idt[0]);printf("%d  %d\n", idt[0].a, idt[0].b); // 输出 100  200return 0;
}

这个例子比较奇怪,奇怪在结构体的访问上

  1. main函数调用了set_gate函数,并且将idt[0]的地址作为参数传了过去
  2. set_gate函数获取了idt[0]的地址之后,直接使用下标去访问结构体内的两个变量

我们知到,一般结构体变量是使用.,结构体指针使用->访问,这种使用下标的挺诡异的,我们分析一下。

  1. 结构体内的两个变量是连续的,都是unsigned long类型
  2. 现在有一个unsigned long*指针指向了结构体内第一个变量(默认指向开头)

在这里插入图片描述

我们可以看到,对于这种模式,不就是动态数组嘛,它们的形式是一样的,访问的时候,a和b可以通过指针的下标访问。

另外就是,由于获取的是指针,也就是地址,而且还不是结构体指针,而是与结构体内元素类型一致的指针,所以,也没有办法通过结构体的方式访问。

从底层来说,这种方式是可行的!需要明白,传参之后,结构体其实在函数set_gate中是看不见的,是消失的

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

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

相关文章

x86异常处理与中断机制(2)中断向量表

补充&#xff1a;事件不仅包含中断和异常&#xff0c;还包含系统调用&#xff0c;这个属于用户主动请求的事件。 上一节&#xff0c;只有一个溢出异常&#xff0c;那么&#xff0c;如果很多异常、中断呢&#xff1f;&#xff08;中断向量表&#xff09; 另外&#xff0c;之前0…

x86异常处理与中断机制(3)中断处理过程

上一节讲完了根据中断类型号找中断服务程序的过程&#xff0c;现在着重说明一下更加完整的中断处理过程吧。 本节以8086时代的中断处理过程为例进行说明&#xff0c;主要分两大部分 硬件处理软件处理 需要注意&#xff0c;这不是绝对的&#xff0c;得看实际情况&#xff0c;…

Linux 0.11 内核解析:中断相关(1)asm.s文件中断处理分析

0 源代码 有两个版本的&#xff0c;一个是带中文注释&#xff0c;Intel格式的&#xff1b;一个是不带注释是AT&T格式的。 Linux 0.11 中文注释版 Linux 0.11 源码&#xff0c;基于《Linux内核完全注释》赵炯 1 asm.s 文件 我们先假设该文件处理的中断是无特权过渡的情况…

【精华文】C语言结构体特殊情况分析:结构体指针 / 基本数据类型指针,指向其他结构体

参考链接&#xff1a;Structure pointer pointing to different structure instance 注&#xff1a;可以查看此篇的问题和唯一的回复&#xff0c;那是相对正确的&#xff0c;不要看comment&#xff0c;有很多错误。 我是拒绝分析这种问题的&#xff0c;因为似乎没有人会这么乱用…

enum in c language

今天说说C语言中的枚举。 参考&#xff1a;Enumeration (or enum) in C 1 定义 定义一个枚举类型很容易&#xff1a; enum aa { a1, a2, a3 };这里 enum是关键字aa是枚举变量&#xff0c;也就是我们自定义类型a1,a2,a3是枚举成员 然后怎么使用呢&#xff1f; 首先&#…

信号量SIGCHLD的使用,如何让父进程得知子进程执行结束,如何让父进程区分多个子进程的结束

本教程基于 Ubuntu 20.10 gcc 10.2.0. 示例程序如果不能正常编译和执行&#xff0c;说明您系统和工具版本与我的不匹配&#xff0c;请自行查阅资料。 0 概述 先给出该信号的描述&#xff1a; SignalValueDescriptionSIGCHLD17Child status has changed (POSIX). Signal sent …

使用gdb调试多进程程序、同时调试父进程和子进程

参考: [1] GDB debugging multi-process programs [2] Debugging programs with multiple processes 根据这两篇参考链接&#xff0c;完全可以实现使用gdb同时调试父进程和子进程。 接下来说明一下可能遇到的坑 gdb8.1版本有bug&#xff0c;设置完set detach-fork-on off&…

Linux安装Ncurses库

参考&#xff1a;How To Install Ncurses Library In Linux 针对Ubuntu说明一下&#xff1a; wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.2.tar.gz&#xff0c;至于最新版本&#xff0c;自己看官网&#xff0c;修改一下版本号即可。tar xzf ncurses-6.2.tar.gzcd nc…

gdb 10.2的安装

参考 [1] GDB-10.2 [2] README for GDB release 个人系统 Ubuntu20.10。 注意gdb10.2需要c11语法&#xff0c;需要安装g 下载安装包wget https://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.xz解压缩tar -xvzf gdb-10.2.tar.xz进入解压之后的目录mkdir buildcd build配置&#xff0c;…

gdb tui的使用

[1] GDB Text User Interface [2] GDB Text User Interface 简单来说&#xff0c;进入gdb之后&#xff0c;使用ctrl x 2就足够了。其他细节请参考上述链接&#xff0c;选一个就可以。

C语言中信号函数(signal)的使用

先来简单谈谈C语言中的信号&#xff08;signal&#xff09; 首先&#xff0c;signal是C语言库中的函数&#xff0c;它实际上是软中断&#xff0c;也就是软件发出的终端&#xff0c;本质来说&#xff0c;类似于int n。 对于接收到该软中断信号的进程&#xff0c;就会停下手头的…

UNIX哲学

参考&#xff1a; 对比Linux与Windows 使用Linux想要做某些事情的时候&#xff0c;就拆开想&#xff0c;想想我需要哪些功能&#xff0c;需要哪些工具&#xff0c;依次怎么执行&#xff0c;然后用管道建立连接&#xff0c;让数据依次流过不同的工具&#xff0c;从而得到最终结果…

fork创建多个子进程

references: [1] how to create two processes from a single Parent [2] fork() in C [3] linux中fork同时创建多个子进程的方法 fork的本质&#xff0c;就是复制&#xff0c;把当前进程复制一份&#xff0c;然后两个进程并发地执行fork后面的语句&#xff0c;区别就是&#x…

wait系统调用

reference:Wait System Call in C 只强调几点&#xff0c;剩下的直接看参考链接内容就好了&#xff0c;不是偷懒&#xff0c;而是里面内容写的很好了&#xff0c;没必要再写一遍了&#xff0c;这种东西就是单纯的系统调用而已&#xff0c;理解了功能&#xff0c;就完事了&#…

Linux进程间通信:共享内存与管道

references: [1] IPC through shared memory [2] Inter Process Communication (IPC) [3] https://www.geeksforgeeks.org/pipe-system-call/ [4] watch command in Linux with Examples 参考链接1和2是介绍了共享内存IPC的简单原理和相关系统调用的使用参考链接3是介绍了管道通…

find command基本使用

find命令通常用于根据文件名查找文件&#xff0c;这是最基本用法。 find [path] -name/-iname [filename] path写要查找的路径&#xff0c;自动递归查找filename写文件名&#xff0c;可以使用通配符*还有其他什么的表达式 具体细节请man find查阅文档。

正则表达式特别需要注意的点:“空“字符的匹配

在正则表达式中&#xff0c;[...]代表1个字符&#xff0c;不管里面有多少字符&#xff0c;最终这个东西的结果都是1个字符。 对于表达式[^a]表达的匹配除了a之外的字符&#xff0c;并且是1个字符。 需要注意的是&#xff0c;有些特殊字符是不会被匹配的。 我们看一个示例&am…

vim多列操作--插入/删除

插入 How to insert text at beginning of a multi-line selection in vi/VimVim Commands 删除 ctrl v使用上下左右键选中一片区域按d删除

vim进行行内某部分的复制剪切粘贴

ctrl v使用方向键选中你要复制的部分 按d&#xff08;剪切&#xff09;或者按y&#xff08;复制&#xff09;再移动到你的目标位置&#xff0c;按p粘贴&#xff08;在正常模式下才行&#xff0c;如果不是&#xff0c;先按esc&#xff09; 这个过程与你操作word文档的复制粘贴…

函数调用堆栈

基于孟宁老师的Linux内核分析 1 int g(int x){ 2 int y x 3;3 return y;4 }5 6 int f(int x){7 int z x 10;8 return g(z);9 }10 11 int main(){12 int a f(8) 1;13 return 0;14…