c - 读入我不应该访问的堆内存?
问题描述
在下面的示例中,我分配了 20 字节的内存来将数组扩展 5 个整数。之后,我将最后一个元素设置为 15,然后将指针重新分配为 4 个字节(1 个整数)。然后我打印数组的前 10 个元素(此时它只包含 6 个),第 9 个(我之前设置为 15)打印时没有警告或错误。
编码 :
#include <stdlib.h>
#include <stdio.h>
int main()
{
int arr[5] = {0};
int *ptr = &arr[0];
ptr = malloc(5 * sizeof(int));
arr[9] = 15;
ptr = realloc(ptr, 1 * sizeof(int));
for (int i = 0; i < 10; ++i)
{
printf("%d\n", arr[i]);
}
free(ptr);
return 0;
}
编译运行后的结果:
0
0
0
0
0
32766
681279744
-1123562100
-1261131712
15
我的问题如下:为什么数组的第 9 个元素还是 15?(为什么我可以访问它?;分配的内存不应该在我的编译器找到的第一个空闲内存块上,并且不连接到数组的缓冲区吗?)
解决方案
您对程序正在做什么的描述都是错误的。
在下面的示例中,我分配了 20 个字节的内存来将数组扩展 5 个整数
不,你没有。你不能延长arr
。这是不可能的。
之后我将最后一个元素设置为 15
否 - 因为您没有扩展数组,所以索引 9 不代表最后一个元素。您只需在数组外部写入。
看看这些行:
int *ptr = &arr[0];
ptr = malloc(5 * sizeof(int));
首先你ptr
指出第一个元素,arr
但在你ptr
指出一些与arr
. 换句话说 - 可以简单地删除第一行(编译器可能会删除)。
在您的程序的其余部分中,您永远不会使用ptr
任何东西。换句话说 -您可以简单地使用删除所有代码ptr
。它没有效果。
所以程序可以简单地是:
int main()
{
int arr[5] = {0};
arr[9] = 15;
for (int i = 0; i < 10; ++i)
{
printf("%d\n", arr[i]);
}
return 0;
}
它具有未定义arr
的行为,因为您访问越界。
推荐阅读
- robotframework - 如何根据运行机器人脚本的浏览器更改关键字中使用的变量?
- javascript - 将 MVC 模型数组传递到 javascript 数组的问题
- kotlin - 仅将标记为 reified 的类型传递给 Kotlin 泛型函数
- r - 计算 90% 并用 R 中的组中位数替换它
- sql - 从一组记录中重新插入失败的记录
- python - 在 R/Python 中分析巨大的 csv 文件并根据文件的分布采样 X%?
- android - hprof 查看器中的 $classOverhead 是什么意思?
- c# - 绑定数据时访问自定义对象字段
- react-native - 如何使用 React-Native-Push-Notification 远程推送通知?
- javascript - 表单 - 传递不带参数名称的选定值