c内存操作感悟(2)
程序员文章站
2022-05-01 10:33:44
...
不从分配的地址开始访问, 希望跳过一些字节, 怎么处理?
如下一段代码正确么(假设文件名为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; }
推荐阅读
-
分享C#操作内存读写方法的主要实现代码
-
C# 操作地址 从内存中读取写入数据(初级)
-
C# 数据操作系列 - 2. ADO.NET操作
-
Lua和C++交互详细总结_2_堆栈的操作
-
剖析iOS开发中Cocos2d-x的内存管理相关操作
-
matlab2c使用c++实现matlab信号操作函数awgn、normrnd、fft、sawtooth、sinc、signcdf、signpdf
-
.NET Core C# 中级篇2-7 文件操作
-
【C++ 语言】C++字符串 ( string 类 | 创建方法 | 控制台输出 | 字符串操作 | 栈内存字符串对象 | string* )
-
C# XML操作 代码大全(读XML,写XML,更新,删除节点,与dataset结合等)第1/2页
-
c内存操作感悟(1)