2

我试图理解以下内容,这三个函数调用如何正常工作,我不确定它在内部是如何工作的,我可以理解第一个很好,但是第二次我用 sizeof 调用 malloc struct 然后打印它,第三次我用结构指针的 sizeof 调用 malloc 并打印它。两者如何可以毫无问题地工作?第二个 malloc 分配的大小为 2*2*int=16 字节,第三个 malloc 分配的大小为 2*pointer=8。而且我在尝试释放 pt2 时得到核心转储,这是在使用 C 和 gcc 的 Linux 上

#include<stdio.h>
#include<stdlib.h>

struct test{
 int field1; 
 int field2;  
};


struct test func(int a, int b) {
 struct test t;
 t.field1 = a;
 t.field2 = b;
 return t;
}

  int main()
{

struct test t;


struct test  pt[2];
pt[0] = func(1,1);
pt[1] = func(2,2);
printf("%d %d\n", pt[0].field1,pt[0].field2);
printf("%d %d\n", pt[1].field1,pt[1].field2);

printf("\n");

struct test *pt1;
pt1 = malloc(sizeof(struct test) * 2);
pt1[0] = func(2,2);
pt1[1] = func(3,3);
printf("%d %d\n", pt1[0].field1,pt1[0].field2);
printf("%d %d\n", pt1[1].field1,pt1[1].field2);
printf("\n");


struct test *pt2;
pt2 = malloc(sizeof(struct test*) * 2);
pt2[0] = func(4,4);
pt2[1] = func(5,5);
printf("%d %d\n", pt2[0].field1,pt2[0].field2);
printf("%d %d\n", pt2[1].field1,pt2[1].field2);

free(pt1);
free(pt2);// I'm getting core dump when trying to free pt2

}

输出低于

1 1
2 2

2 2
3 3

4 4
5 5
4

2 回答 2

3
pt1 = malloc(sizeof(struct test) * 2);

这个说法是正确的。

pt2 = malloc(sizeof(struct test*) * 2);

这种说法是错误的。它在表达式中使用了错误的类型,sizeof因此分配了错误的内存量。通常的做法是使用sizeof(*var)而不是sizeof(type)完全避免这个问题。

pt2 = malloc(sizeof(*pt2) * 2);

在像您这样的 32 位平台上,错误的 malloc 仅分配所需内存量的一半,因此分配p2[1]调用未定义的行为。您的程序写入不属于它的内存。这是 C,几乎没有运行时错误检查。而不是立即崩溃,您通常只会覆盖内存中 malloc'ed 块旁边的任何内容。

缓冲区溢出是一个无声的杀手。谁知道你刚刚覆盖了什么?它可以是任何东西,真的。尝试释放 pt2 会触发核心转储也就不足为奇了。指针错误在 C 语言中是令人讨厌的,因为您的程序经常会在最终崩溃之前跛行一段时间。崩溃的代码不一定是错误所在。

于 2012-12-20T02:59:56.047 回答
1

您没有为pt2. 该声明:

pt2 = malloc(sizeof(struct test*) * 2)

只是为两个指向结构的指针分配空间,没有足够的空间给结构本身。

您正在写超出pt2数组的范围。这是未定义的行为,在您的情况下会导致 crash on free。如果这是更复杂程序的一部分,则此类问题可能会导致不同类型的内存损坏...

于 2012-12-20T03:02:32.950 回答