`
jimmee
  • 浏览: 537977 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

c内存操作感悟(2)

阅读更多

不从分配的地址开始访问, 希望跳过一些字节, 怎么处理?

 

如下一段代码正确么(假设文件名为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;
}

 

 

0
0
分享到:
评论

相关推荐

    2022年大学c语言学习心得感悟.docx

    3. **指针**:指针是C语言的一大特色,它能存储内存地址,允许直接操作内存,提供了高效的数据操作方式。理解指针需要掌握指针的声明、初始化、解引用以及指针运算。 4. **数组与字符串**:数组是一组相同类型的...

    Java学习总结[C程序员的感悟]

    ### Java学习总结:C程序员的感悟 #### 第一章:Java入门(C与Java的差异) ##### 基本数据类型: Java的数据类型与C语言相比,在命名上有一定区别,例如整型在C中为`int`,而在Java中也为`int`,但Java的数据...

    C语言指针学习笔记

    数据类型不仅决定了变量所占用的内存大小,还决定了变量的操作方式。 ##### 1. 基本数据类型 - **整型 (int)** - 用于存储整数值。 - **字符型 (char)** - 用于存储单个字符。 - **浮点型 (float/double)** - `...

    2022年C语言实习心得5篇精选集合最新.docx

    - 指针是C语言的灵魂,它提供了直接访问内存地址的能力,使得动态内存管理和高效的数据操作成为可能。 - 指针与数组、结构体的结合使用,能够实现更灵活的数据结构,但也是学习中的一大难点。 6. **学习策略**: ...

    C语言学习心得

    因此,我们需要学习 C 语言的注意事项,例如指针和数组的区别、数组名和函数名的使用、结构体中的内存对齐、指针数组和数组指针的区别等。 学习 C 语言需要我们耐心、细心、实践和总结。只有通过大量的上机实践、多...

    我的编程感悟(中文PDF)(共37M二分卷)分卷二

    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程序至关重要。书中可能还提到了数组和字符串的操作,这些是C语言笔试和机试中经常考察的知识点。此外,数字运算符的使用也是编程中不可或缺的一部分,作者可能在书中对各种运算符...

    C语言课程设计报告_我的心得体会

    在“C语言课程设计报告_我的心得体会”这个主题中,我们可以深入探讨C语言的基本概念、课程设计的关键要素以及个人在学习过程中的体验和感悟。C语言是一种基础且强大的编程语言,广泛应用于系统开发、嵌入式系统、...

    操作系统课程设计操作系统 大三的课程设计 报告和源代码 相当的实用。

    2. 提供一个总体概述,解释高速缓冲区在整个操作系统中的作用和重要性。 3. 对每个源代码模块进行详细分析,特别是C语言函数的功能描述,利用图形工具如Visio绘制流程图以直观展示其工作流程。 4. 分享分析过程中的...

    操作系统实验课代码

    通过实验掌握1-2种操作系统的界面,了解命令和调用的工作流程,深入理解操作系统的内部运作机制。目标是使学生能够熟练使用操作系统环境,掌握各种命令和功能,有效利用计算机资源。 #### 示例 以Windows和Linux/...

    C语言深度剖析

    最后,可能还包括了C语言的标准化历程,如C89、C99、C11等标准的差异,以及如何遵循标准编写跨平台的C代码。这有助于读者编写出更规范、更具移植性的程序。 通过《C语言深度剖析》这本书,读者不仅可以全面掌握...

    我的编程感悟(中文PDF)(共37M二分卷)分卷一

    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 ...

    2022年c语言的学习心得.docx

    标题中的“2022年c语言的学习心得”表明了本文是关于学习C语言的个人体验和感悟,而“考试”标签则暗示了这可能是针对考试准备或技能考核的学习总结。主要内容提到了学习C语言的过程,包括遇到的问题、解决方法以及...

    [14本经典Android开发教程]-8-Linux内核阅读心得体会

    读核感悟 2 读核感悟 Linux内核启动 内核的生成 2 读核感悟 Linux内核启动 从hello world说起 3 读核感悟 Linux内核启动 BIOS 5 读核感悟 Linux内核启动 setup辅助程序 6 读核感悟 Linux内核启动 内核解压缩 8 读核...

    LinuxC语言学习感悟

    "Linux C语言学习感悟" 在 Linux 和 C 语言学习的过程中,我逐渐体验到了蜕变的重要性。从一开始的无知到现在的自信,都是一步步的成长。经历了指针、数组、链表、队列、树、IO 和网络编程等知识点的学习和实践,才...

Global site tag (gtag.js) - Google Analytics