提问人:hina abbasi 提问时间:8/17/2012 最后编辑:Communityhina abbasi 更新时间:8/17/2012 访问量:514
我想了解 C [duplicate] 中的 malloc() 和 realloc()
I want to understand malloc() and realloc() in C [duplicate]
问:
可能的重复:
在 malloc() 之后写入指针越界不会导致错误
我正在尝试一个非常基本的程序来为只有 2 个的数组分配内存。我只为 2 分配内存,即 和 :为什么可以使用并且它运行良好?ints
ints
array[0]
array[1]
array[2]
#include <stdio.h>
int main(int argc, char *argv[])
{
int *array;
int i;
array = NULL;
array = malloc(sizeof(int)*2);
array[0] = 2;
array[1] = 3;
array[2] = 4;
for( i = 0; i<3 ; i++)
printf("%d\n", array[i]);
return 0;
}
输出:
2
3
4
答:
这似乎有效,因为 C 不会阻止您访问不属于您的内存。即使它看起来可以工作,代码仍然不正确,明天可能无法工作。您通过写入/读取不属于您的内存来调用未定义的行为。
因为 C 不会试图握住你的手。您可以读取/写入未分配的内存,但您很可能从其他对象修改/提取数据,或者只是提取垃圾数据。
当您创建数组时,您会得到一个指向内存中地址的指针,并且可以随心所欲地使用它。通过分配内存,可以防止在该内存块中创建其他对象,就像为阵列保留它一样。但是,超过该数量没有限制,您可以读取和写入任何您想要的地方。这样做的好处是你有相当大的权力,可以直接操纵地址。缺点是,你很容易导致你的程序分崩离析,我在属于其他对象的内存位置上操纵信息。
从中可以得出的结论是,C 语言赋予了你巨大的权力,而这种权力的使用完全取决于你。
在此处阅读答案以更好地理解
它本质上是内存损坏,如此处所述
尝试使用一个非常大的数字而不是 4,它会产生错误,因为当您调用 malloc() 时,会为您从更大的页面中雕刻出一小块内存。因此,超出区块范围的写作并不一定意味着你会崩溃。在 array[4] 中,您没有在为该初始块分配的页面边界之外写入,因此从技术上讲,您是在写入一个有效的映射地址。源
pb2q 是绝对正确的。验证是否正在访问未分配内存的一种方法是执行以下操作:
array = calloc(sizeof(int) * 2);
for (i = 0; i < 3; i++)
printf("%d\n", array[i]);
您可能会收到以下输出:
0
0
*random value*
评论
我相信它有效,因为您的实现在内存块之前和之后放置了一些信息,并且可能在块中分配(例如,将分配请求四舍五入到最接近的 64 字节)。ed 内存必须能够被释放,这需要一些关于其大小等的信息,这些信息放在分配的内存之前和/或之后。malloc
malloc
如果数据是以块形式分配的,那么在完全填充一个“块”的情况下,您将达到一些限制,并且读取将在“块”的末尾。我们可以按如下方式进行测试:array[n]
int main() {
int i;
char * a;
for (i = 1; i < 10000; i++) {
a = malloc(i);
a[i] = 'x';
printf("%d %c\n", i, a[i]);
free(a);
}
return 0;
}
它越来越大的内存块,并检查越界段错误。我得到的截断输出是:malloc
1 x
[...]
58 x
59 x
60 x
61 x
62 x
*** glibc detected *** ./a.out: free(): invalid next size (normal): 0x0a041008 ***
[...]
即尝试执行失败,因为它破坏了我之前谈论的元数据。a = malloc(63); a[63] = 'x';
提示:您必须避免在函数上使用 printf......仅在 main() (:
当您使用 malloc 和 realloc 时,C 将分配大小为 int 的内存。它不会分配另一个“位置”来放置一个数字。唯一发生的情况是,如果您输入的数据具有与 int 相同的字节大小。这是通常会发生的事情,因为 C 不会告诉你数组大小是否已满。要小心。
评论