【问题标题】:pointer to array of struct指向结构数组的指针
【发布时间】:2012-12-07 12:35:40
【问题描述】:

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

#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

【问题讨论】:

    标签: c linux malloc


    【解决方案1】:
    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 语言中是令人讨厌的,因为您的程序经常会在最终崩溃之前跛行一段时间。崩溃的代码不一定是错误所在。

    【讨论】:

    • 非常感谢,我不知道,显然:),那么哪个是正确的,如果我理解正确,第一个 malloc 是正确的方法,对吗?
    【解决方案2】:

    您没有为pt2 分配足够的空间。声明:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-03
      • 2016-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多