0

Hi I have following code

#include <stdio.h>
#include <conio.h>
typedef struct test
{
    int a;
    int b;
    int c[10];
}tester;

typedef struct done
{
    tester* t;
    int nn;
}doner;

void main()
{
    doner d;
    d.t = (tester*)malloc(sizeof(d.t));
    d.t->a = 10;
    d.t->c[0] = 10;
    printf("%d\n", d.t->a);
    getch();
    return;
}

I think the statement:

d.t = (tester*)malloc(sizeof(d.t));

is incorrect it should be:

d.t = (tester*)malloc(sizeof(tester));

but when I run this code it is not crashing please let me the why is this.

4

4 回答 4

1

它没有崩溃的事实是因为它具有未定义的行为。正确的代码是第二个,但不需要强制转换。

d.t = malloc(sizeof(tester));

此外,您需要释放 malloc 的指针。

在许多系统上,写入 malloc 的缓冲区时不会检查堆,而只会在释放分配的内存时检查堆。在这种情况下,当您释放内存时,您可能会遇到某种崩溃。

于 2012-07-18T09:53:05.333 回答
1

它没有崩溃的事实是这些内存分配错误如此阴险且难以检测的一个重要原因。你的程序只分配一个结构,并没有填满它,所以它运行超过分配给它的内存量这一事实不会影响其他任何东西。

malloc如果您的程序更多地使用动态分配的内存,那么对/的调用free将触发崩溃,因为您的结构覆盖了堆的链接元数据,或者程序的其他部分写入它们自己的 malloc 数据将覆盖您的结构。不管怎样,都不好看。

于 2012-07-18T09:54:59.913 回答
0

默认情况下,链接器要求操作系统在启动时为程序分配 1MiB 的(堆栈)内存。您的程序不会崩溃,因为所有引用仍位于操作系统为您的程序保留的同一内存(同一地址空间)中。从技术上讲,您尚未分配该内存,但由于指针仍在有效内存范围内,因此您的程序可以访问它。这就像在大多数情况下,您可以写入 dt->c[10](尽管有效索引为 0-9)当使用与分配内存之外的内存位置相对应的指针时会发生崩溃。如果您有兴趣,请使用Google Page Fault进行详细了解。

于 2012-07-18T10:48:07.670 回答
0

你是对的。应该是sizeof(tester),因为d.t只是一个指针。

现在,如果你写sizeof(d.t)你调用未定义的行为,这不是崩溃的保证。该程序可能运行正确、运行不正确、崩溃或订购披萨。无法保证具有未定义行为的程序会发生什么,即使在导致它的构造之前也是如此。

作为freeedmalloc内存 - 在这个小示例程序中,您无需担心它,因为系统会在程序退出后释放内存,但通常您应该尝试释放您分配的任何内容以避免大型程序中的内存泄漏。

于 2012-07-18T09:53:28.657 回答