x64平台下采用malloc申请的内存,用memset清零时报错???????

问题详述

如下示例代码,在x86平台下可以正常运行,改成x64平台报错;(double类型同样会报错)

#include <stdio.h>
#include <string.h>
int main() {
	double b[10];
	memset((void*)b, 0, 10 * sizeof(double));
	for (char i = 0; i < 10; i++) printf("%f\n", b[i]);

	double* a = (double*)malloc(10 * sizeof(double));
	for (int i = 0; i < 10; i++) printf("%d--%p--%p\n", i, a + i, b + i);
	memset((void*)a, 0, 10 * sizeof(double));
	for (char i = 0; i < 10; i++) printf("%f\n", a[i]);

	free(a);

	return 0;
}

在x64平台下,数组b可以正常memset清零,但是使用malloc申请内存的数组a在memset清零时会报错,具体错误如下:
image

我们输出了两个数组的地址,如下图:
image

可以发现,发生访问冲突的地址是数组a的第三个元素。

在x86平台下正常运行的结果如下:
image

问题分析

对比x86下数组地址,和对比x64两种数组地址,发现大概率是地址问题,报错地址高位是F,正常没有报错地址高位为0;
然后去查找memset源码发现:

void *(memset) (void *s,int c,size_t n)
{
    const unsigned char uc = c;
    unsigned char *su;
    for(su = s;0 < n;++su,--n)
        *su = uc;
    return s;
}

memset源码将 (void*) 类型的指针 转换成 (unsigned char*)类型的指针,问题出现在 *su 取值这里。

然后我单独去测 取值符号* 在x64平台下也会报相同的错误。大概率就是它惹的祸。大概率地址越界了

猜测原因

根据上面发现的问题,猜测是由于 x64平台下,malloc申请的空间越界,导致寻址报错。

弱智错误

错误原因:没有引用malloc的头文件 stdlib.h ,编译器为什么没有报错(猜测应该是别的地方有malloc的错误是实现)

  • 在32位程序中,在没有添加头文件 stdlib.h 时使用malloc函数,编译运行都可以通过
  • 在64位程序中,在没有添加头文件 stdlib.h 时使用malloc函数,编译可以通过,运行时报错,无法访问申请的内存
posted @ 2023-01-31 11:16  小超不挑食  阅读(180)  评论(1编辑  收藏  举报