不从分配的地址开始访问, 希望跳过一些字节, 怎么处理?
如下一段代码正确么(假设文件名为test.c)?
#include <stdio.h> #include <stdlib.h> int main(void) { void *p = malloc(20); printf("%p\n", p); char *t = (char *)(p + 1); printf("%p\n", t); free(p); return 0; }
使用gcc -S -masm=intel test.c生成intel
格式的汇编
mov DWORD PTR [esp], 20 call _malloc mov DWORD PTR [esp+28], eax mov eax, DWORD PTR [esp+28] mov DWORD PTR [esp+4], eax mov DWORD PTR [esp], OFFSET FLAT:LC0 call _printf mov eax, DWORD PTR [esp+28] add eax, 1 mov DWORD PTR [esp+24], eax mov eax, DWORD PTR [esp+24] mov DWORD PTR [esp+4], eax mov DWORD PTR [esp], OFFSET FLAT:LC0 call _printf mov eax, DWORD PTR [esp+28] mov DWORD PTR [esp], eax call _free
可以看到(char *)(p + 1), 仅仅是将指针p进行加1运算, 其实, 进一步是考虑, 对指针加N, 指针前进"当前指针指向的数据类型的长度*N", 但是void *, 是不知道具体的数据类型是怎样的, gcc这里是将这种情况当做char类型来处理了, 所以地址直接加1, 编译也能通过.
但是同样的代码, 在vc中是通不过编译的, char *t = (char *)(p + 1);这一行和预期的一样, 报错如下:
error C2036: “void *”: 未知的大小
如果要都能通过编译, 其实可以两种做法:
方法一, 其实一个指针可以强制转换为整数的, 就是这个指针的地址值, 对这个值可以做加减, 之后整数也是可以强制转换为指针的, 当做地址使用.
#include <stdio.h> #include <stdlib.h> int main(void) { void *p = malloc(20); printf("%p\n", p); long pt = (long)p; char *t = (char *)(pt + 1); printf("%p\n", t); free(p); return 0; }
方法二, 常规方法, 先得到地址, 指针加+1.
#include <stdio.h> #include <stdlib.h> int main(void) { void *p = malloc(20); long pt = (long)p; char *t = (char *)(p); t++; printf("%p\n", p); printf("%p\n", t); free(p); return 0; }
相关推荐
3. **指针**:指针是C语言的一大特色,它能存储内存地址,允许直接操作内存,提供了高效的数据操作方式。理解指针需要掌握指针的声明、初始化、解引用以及指针运算。 4. **数组与字符串**:数组是一组相同类型的...
### Java学习总结:C程序员的感悟 #### 第一章:Java入门(C与Java的差异) ##### 基本数据类型: Java的数据类型与C语言相比,在命名上有一定区别,例如整型在C中为`int`,而在Java中也为`int`,但Java的数据...
数据类型不仅决定了变量所占用的内存大小,还决定了变量的操作方式。 ##### 1. 基本数据类型 - **整型 (int)** - 用于存储整数值。 - **字符型 (char)** - 用于存储单个字符。 - **浮点型 (float/double)** - `...
- 指针是C语言的灵魂,它提供了直接访问内存地址的能力,使得动态内存管理和高效的数据操作成为可能。 - 指针与数组、结构体的结合使用,能够实现更灵活的数据结构,但也是学习中的一大难点。 6. **学习策略**: ...
因此,我们需要学习 C 语言的注意事项,例如指针和数组的区别、数组名和函数名的使用、结构体中的内存对齐、指针数组和数组指针的区别等。 学习 C 语言需要我们耐心、细心、实践和总结。只有通过大量的上机实践、多...
7.2.3 SIMD技术在C语言环境下的使用 196 7.2.4 MMX 编码技巧 197 7.2.5 SIMD 的应用举例 201 7.2.6 SIMD编程注意要点 203 7.2.7 SIMD的性能检测 204 第8章 引擎中的优化 205 8.1 Blit的优化 207 8.2 脏矩形优化 209 ...
对于成绩的管理,可能需要使用链表或数组来存储大量的学生数据,这涉及到动态内存分配和数据结构的操作。 接着,系统需要有用户交互界面,通常以命令行菜单的形式呈现。这需要掌握控制台输入输出操作,如`printf`和...
正确管理内存对于编写高效、稳定的C程序至关重要。书中可能还提到了数组和字符串的操作,这些是C语言笔试和机试中经常考察的知识点。此外,数字运算符的使用也是编程中不可或缺的一部分,作者可能在书中对各种运算符...
2. 提供一个总体概述,解释高速缓冲区在整个操作系统中的作用和重要性。 3. 对每个源代码模块进行详细分析,特别是C语言函数的功能描述,利用图形工具如Visio绘制流程图以直观展示其工作流程。 4. 分享分析过程中的...
通过实验掌握1-2种操作系统的界面,了解命令和调用的工作流程,深入理解操作系统的内部运作机制。目标是使学生能够熟练使用操作系统环境,掌握各种命令和功能,有效利用计算机资源。 #### 示例 以Windows和Linux/...
最后,可能还包括了C语言的标准化历程,如C89、C99、C11等标准的差异,以及如何遵循标准编写跨平台的C代码。这有助于读者编写出更规范、更具移植性的程序。 通过《C语言深度剖析》这本书,读者不仅可以全面掌握...
7.2.3 SIMD技术在C语言环境下的使用 196 7.2.4 MMX 编码技巧 197 7.2.5 SIMD 的应用举例 201 7.2.6 SIMD编程注意要点 203 7.2.7 SIMD的性能检测 204 第8章 引擎中的优化 205 8.1 Blit的优化 207 8.2 脏矩形优化 209 ...
本项目通过C语言实现了飞机售票系统的基本功能,不仅涵盖了数据结构的设计与实现,还涉及到了文件操作等内容。对于初学者来说,这是一个非常好的实践项目,能够帮助他们巩固所学知识,提高编程能力。同时,该项目也...
标题中的“2022年c语言的学习心得”表明了本文是关于学习C语言的个人体验和感悟,而“考试”标签则暗示了这可能是针对考试准备或技能考核的学习总结。主要内容提到了学习C语言的过程,包括遇到的问题、解决方法以及...
读核感悟 2 读核感悟 Linux内核启动 内核的生成 2 读核感悟 Linux内核启动 从hello world说起 3 读核感悟 Linux内核启动 BIOS 5 读核感悟 Linux内核启动 setup辅助程序 6 读核感悟 Linux内核启动 内核解压缩 8 读核...
"Linux C语言学习感悟" 在 Linux 和 C 语言学习的过程中,我逐渐体验到了蜕变的重要性。从一开始的无知到现在的自信,都是一步步的成长。经历了指针、数组、链表、队列、树、IO 和网络编程等知识点的学习和实践,才...
理解指针操作是学习C语言的关键,但其抽象性往往让初学者感到困扰。例如,如何动态地分配内存,如何通过指针操作数组,以及如何使用指针进行函数参数传递,都需要深入理解。 链表是C语言中的另一个重要概念,它是一...