2012-07-18 60 views
0

您好我有下面的代码指针在C结构体变量

#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; 
} 

我认为声明:

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

不正确,它应该是:

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

但是当我运行这段代码不会崩溃,请让我这是为什么。

+0

有什么问题,每个bug都不能保证崩溃 – perreal 2012-07-18 09:51:20

+0

1)conio.h是一个非标准的头文件。 2)main()应该返回int。 3)不要投射malloc()的返回值。4)#include 5)'d.t = malloc(sizeof * d.t);' – wildplasser 2012-07-18 09:57:54

回答

1

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

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

另外,你需要释放malloc分配指针。

在许多系统上,写入malloc缓冲区时不会检查堆,但只有释放分配的内存时才会检查堆。在这种情况下,释放内存时可能会发生某种类型的崩溃。

0

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

现在如果你写sizeof(d.t)你调用Undefined Behavior这不是崩溃的保证。该程序可能运行正常,运行不正确,崩溃或订购比萨饼。无法保证未定义行为的程序会发生什么情况,即使在构建它的结构之前。

由于free荷兰国际集团的malloc版内存 - 在这个小样本程序,你不必担心,因为系统会在程序退出后释放内存,但一般而言,您应该尝试任何你自由”已被分配以避免较大程序中的内存泄漏。

1

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

如果你的程序更加使用动态分配的内存中,然后要么因为你的结构改写堆的链接程序写作的元数据,或其他部件自己malloc分配到malloc/free的通话将触发崩溃数据会覆盖你的结构。无论哪种方式,不漂亮。

0

默认情况下,链接器要求操作系统在启动时为程序分配1MiB的(堆栈)内存。你的程序不会崩溃,因为所有的引用仍然在你的程序的操作系统保留的相同的内存(相同的地址空间)。从技术上讲,你没有分配内存,但由于指针仍然在有效的内存范围内,所以你的程序可以访问它。 这就像在大多数情况下可以写入d.t-> c [10](尽管有效索引为0-9)。 当使用指针对应于分配内存外的内存位置时,会发生崩溃。谷歌页面错误的详细了解,如果你有兴趣。