realloc在不同编译环境下的不一致问题与C数组指针

realloc在不同编译环境下的不一致问题

我们知道realloc是在原有地址空间下重新分配地址空间大小,原先已经写在地址中的数据,在函数执行后会再写入新分配的空间中去,笔者抱着试一试的心态编写代码实验,发现了一些问题与原因探索与读者分享。

#include<stdio.h>
#include<stdlib.h>
int main(){
	int i,len = 10;
	int *a = (int *)malloc(sizeof(int) * len);
	for(i = 0;i < len;i++){
		a[i] = i;
	}
	realloc(a,20);
	len = 20;
	for(i = 0;i < len;i++){
		printf("%d ",a[i]);
	}
	free(a);
	return 0;
}

下面这张图是在dev c++里面执行出的结果
在这里插入图片描述
下面这张图是vc2010编译器执行出的结果
在这里插入图片描述
与我们原先认为的有分歧的情况出现vc2010中,下面对上面程序的反汇编程序进行分析
值得一提的是,vc用的是X86架构下的汇编语言
下面是两条关键程序的汇编代码

int *a = (int *)malloc(sizeof(int) * len);

00AA34A5 mov eax,dword ptr [len]
00AA34A8 shl eax,2
00AA34AB mov esi,esp
00AA34AD push eax
00AA34AE call dword ptr [__imp__malloc (0AA82B0h)]
00AA34B4 add esp,4
00AA34B7 cmp esi,esp
00AA34B9 call @ILT+300(__RTC_CheckEsp) (0AA1131h)
00AA34BE mov dword ptr [a],eax

realloc(a,20);

00AA34E9 mov esi,esp
00AA34EB push 14h
00AA34ED mov eax,dword ptr [a]
00AA34F0 push eax
00AA34F1 call dword ptr [__imp__realloc (0AA82B4h)]
00AA34F7 add esp,8
00AA34FA cmp esi,esp
00AA34FC call @ILT+300(__RTC_CheckEsp) (0AA1131h)
可以看到,真正的内核函数并不存在于这里,命令还是有继续调用malloc和realloc的内部命令的,再将程序跳转到对应的目标地址(这里笔者重新编译了,所以地址会有变化,但汇编的内容是一样的)。

__imp__malloc:

00CF82B0 push eax
00CF82B1 nop
00CF82B2 jo __imp__free+52h (0CF830Eh)

__imp__realloc:

00CF82B4 xor byte ptr [ebx+7EF05A71h],cl
00CF82BA pop edx

可以看到realloc只有异或操作,并没有实际的赋值操作。
在这里插入图片描述
其中c1的值是8,ascii的值是56,但是是一个字节的异或
__RTC_CheckEsp是检查内存溢出的命令,程序的反汇编无法到达这条命令的地址。
所以推断问题是出在异或中了,但问题在于1个字节的异或不可能改变这么多信息的,一个int就占了4字节,很是不理解,感觉很有毒。但由于笔者能力有限,只能探索到这,如果读者有所发现可以一起探讨,这就属于科研生活中的小插曲了。
补充:这里出现的问题与后面申请数值指针无关,首先内存空间一般够用且去掉后面的代码问题仍在。很遗憾devc++没有反汇编的功能,不能进行对比。当然也有可能问题只出现在我这里,因为安装的原因,编译器的原因等等,可能在读者的编译环境下就运行正常了,也不是不可能,只能说这个问题太硬。

下面再补充一些冷知识,就不再重新写一篇blog了,其实都归属于指针部分的内容,写在一起也无伤大雅。

数组指针

这是在动态二维数组的申明中看到的,这里记录一下
数字指针顾名思义,其元素内容就是指针地址
指针数组见C程序涉及的307页

	int (*b)[2]=(int(*)[2])malloc(sizeof(int)); 
	printf("\n%d",b[100]);

在这里插入图片描述
而且有趣的一点现象是,当访问动态数组的下标超过原有的数组大小时,不会发生地址越界,而是访问到一段以原地址加上地址偏移量为地址的内容(当然我们没有定义过,访问一段没受限制的内存)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原创小白变怪兽

帮助原创小白成为怪兽吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值