简体   繁体   English

在c中struct的成员中间调用free时会发生什么?

[英]What happen when call free on middle of struct's member in c?

I just wonder what's happen when free() called about member of struct tonight. 我只是想知道当free()今晚调用struct的成员时会发生什么。 Let see below simple code in c. 让我们在下面的c中看到简单的代码。

typedef struct {
    int c[5];
    int a[10];
    int *b;
}stma;
int main() {
    stma *he = (stma*)malloc(sizeof(stma));
    int *ac = he->a;
    free(ac); //This point is crash.
    return 0;
}

The free make crash. 免费的make崩溃。 But next code is work well. 但是下一个代码运行良好。

typedef struct {
    int c[5];
    int a[10];
    int *b;
}stma;
int main() {
    stma *he = (stma*)malloc(sizeof(stma));
    int *ac = he->c; //This point is changed.
    free(ac); //Work well.
    return 0;
}

Of course, I could think second will work well and first is not correct code too. 当然,我想第二可以很好地工作,第一也不是正确的代码。

What I wonder is what is happen during first execution. 我想知道的是第一次执行时会发生什么。 free() free 'a' variable, the middle of struct, not address of struct. free()释放'a'变量,结构的中间,而不是结构的地址。

he->a is not malloced, dynamically assigned and couldn't be free. he-> a未分配,不会动态分配,并且无法释放。 In this case, he->c memory address is 00D2Ad50 and he->a is 00D2AD64. 在这种情况下,he-> c存储器地址为00D2Ad50,而he-> a为00D2AD64。 The struct variable will be placed in heap by malloc(). struct变量将通过malloc()放入堆中。 he->c have same address of 'he'. he-> c具有相同的地址“ he”。 And he->c + 4*5 is he->a. 他-> c + 4 * 5是他-> a。 he->a is also in heap? 他->一个也在堆吗? Then, what happen on free(he->a)? 那么,免费(he-> a)会发生什么?

The first of your examples is undefined behavior . 您的第一个示例是未定义的行为 You try to free what you didn't get from a memory management function ( malloc ). 您尝试释放从内存管理功能( malloc )中得到的东西。 And like undefined behavior means - it may crash, work or anything - the behavior is not specified by the standard. 就像未定义的行为手段一样-它可能崩溃,起作用或发生任何事情-该行为不是标准规定的。 So anything may happen. 所以什么都可能发生。

From § 7.22.3.3 ¶2 从§ 7.22.3.3 ¶2

Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined. 否则,如果参数与内存管理函数先前返回的指针不匹配,或者如果通过调用free或realloc释放了空间,则该行为是不确定的。 1 1个

Your second example is not undefined behavior and is perfectly legal - this is validated by the quote given below. 您的第二个示例不是未定义的行为,并且是完全合法的-这通过下面给出的引用进行了验证。 From § 6.7.2.1 ¶15 N1570 从§ 6.7.2.1 ¶15 N1570

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. 在结构对象中,非位字段成员和位字段所在的单元的地址按照声明的顺序增加。 A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. 指向经过适当转换的结构对象的指针指向其初始成员(或者,如果该成员是位字段,则指向它所驻留的单元),反之亦然。 There may be unnamed padding within a structure object, but not at its beginning. 结构对象内可能存在未命名的填充,但在其开始处没有。

As there is no padding involved then the address of the first member is necessarily the one returned by the malloc previously called. 由于不涉及填充,因此第一个成员的地址必然是先前调用的malloc返回的地址。 By the quote previously mentioned about free this is alright. 通过前面提到的关于free的报价,这没关系。

Also another point to be made is - not casting the return value of malloc and checking the return value of malloc . 另外要提出的另一点是-不投的返回值malloc和检查返回值malloc

1. One violation of this would when you try to free memory from the middle of the allocated object or something you didn't allocate at all using memory management function. 1.当您尝试从分配的对象的中间释放内存或使用内存管理功能根本没有分配的内存时,可能会发生这种情况。 int *a = malloc(sizeof*a * 5) and then calling free(&a[5]) this will be undefined behavior or even this int a[10]; int *a = malloc(sizeof*a * 5)然后调用free(&a[5])这将是不确定的行为,甚至是int a[10]; and then calling free(&a[5]) would be one. 然后调用free(&a[5])将是一个。 For dynamic allocation, you can always shrink the allocated space using realloc (freeing the memory that is not needed.) 对于动态分配,您始终可以使用realloc缩小分配的空间(释放不需要的内存。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM