我想了解 C [duplicate] 中的 malloc() 和 realloc()

I want to understand malloc() and realloc() in C [duplicate]

提问人:hina abbasi 提问时间:8/17/2012 最后编辑:Communityhina abbasi 更新时间:8/17/2012 访问量:514

问:

这个问题在这里已经有答案了:
11年前关闭。

可能的重复:
malloc() 之后写入指针越界不会导致错误

我正在尝试一个非常基本的程序来为只有 2 个的数组分配内存。我只为 2 分配内存,即 和 :为什么可以使用并且它运行良好?intsintsarray[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 malloc 动态内存分配

评论


答:

3赞 pb2q 8/17/2012 #1

这似乎有效,因为 C 不会阻止您访问不属于您的内存。即使它看起来可以工作,代码仍然不正确,明天可能无法工作。您通过写入/读取不属于您的内存来调用未定义的行为。

0赞 HypnoticSheep 8/17/2012 #2

因为 C 不会试图握住你的手。您可以读取/写入未分配的内存,但您很可能从其他对象修改/提取数据,或者只是提取垃圾数据。

当您创建数组时,您会得到一个指向内存中地址的指针,并且可以随心所欲地使用它。通过分配内存,可以防止在该内存块中创建其他对象,就像为阵列保留它一样。但是,超过该数量没有限制,您可以读取和写入任何您想要的地方。这样做的好处是你有相当大的权力,可以直接操纵地址。缺点是,你很容易导致你的程序分崩离析,我在属于其他对象的内存位置上操纵信息。

从中可以得出的结论是,C 语言赋予了你巨大的权力,而这种权力的使用完全取决于你。

3赞 kitwalker 8/17/2012 #3

在此处阅读答案以更好地理解

它本质上是内存损坏,如此处所述

尝试使用一个非常大的数字而不是 4,它会产生错误,因为当您调用 malloc() 时,会为您从更大的页面中雕刻出一小块内存。因此,超出区块范围的写作并不一定意味着你会崩溃。在 array[4] 中,您没有在为该初始块分配的页面边界之外写入,因此从技术上讲,您是在写入一个有效的映射地址。

2赞 laker 8/17/2012 #4

pb2q 是绝对正确的。验证是否正在访问未分配内存的一种方法是执行以下操作:

array = calloc(sizeof(int) * 2); 
for (i = 0; i < 3; i++)
    printf("%d\n", array[i]);

您可能会收到以下输出:

0
0
*random value*

评论

0赞 parallelgeek 8/17/2012
是否有任何函数可以放置我的“信号值”来填充内存块?
0赞 huon 8/17/2012 #5

我相信它有效,因为您的实现在内存块之前和之后放置了一些信息,并且可能在块中分配(例如,将分配请求四舍五入到最接近的 64 字节)。ed 内存必须能够被释放,这需要一些关于其大小等的信息,这些信息放在分配的内存之前和/或之后。mallocmalloc

如果数据是以块形式分配的,那么在完全填充一个“块”的情况下,您将达到一些限制,并且读取将在“块”的末尾。我们可以按如下方式进行测试: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';

0赞 João Victor 8/17/2012 #6

提示:您必须避免在函数上使用 printf......仅在 main() (:

当您使用 malloc 和 realloc 时,C 将分配大小为 int 的内存。它不会分配另一个“位置”来放置一个数字。唯一发生的情况是,如果您输入的数据具有与 int 相同的字节大小。这是通常会发生的事情,因为 C 不会告诉你数组大小是否已满。要小心。