从动态分配的结构数组中释放特定元素

时间:2015-05-24 10:40:04

标签: c struct dynamic-memory-allocation dynamic-arrays

我有一个简单的结构if let toWatchOldMessage: AnyObject = wormhole.messageWithIdentifier("toWatch") { println("*ic getOldWormholeMessages toWatchOldMessage \(toWatchOldMessage)") } else { println("*ic getOldWormholeMessages toWatchOldMessage no message") } s_person,它接受​​我们想要构造的constructor(int number)的数量并返回指向它的指针。

在这个例子中,我构建了2 s_person,并为其属性name指定了值。它有效。

s_person

当我尝试释放元素0并再次打印值时,它可以正常工作。

但如果我尝试释放元素1并打印值,它就会崩溃。

那么,如何为这个结构数组中的特定元素释放内存?

它是一种为#include<stdio.h> #include<stdlib.h> #define MAX_NAME 50 typedef struct s_person { char *name; double grade; }s_person; s_person* construct(int number){ int each; s_person *person = (s_person*)malloc(sizeof(s_person) * number); if(person){ for(each=0; each<number; each++){ person[each].name = (char*)malloc(sizeof(char)); } } return person; } main() { s_person *person = construct(2); person[0].name = "steven"; person[1].name = "michael"; printf("%s %s\n", person[0].name, person[1].name); // This works free(&person[0]); printf("%s %s\n", person[0].name, person[1].name); //This doesn't work free(&person[1]); // Crashes here printf("%s %s\n", person[0].name, person[1].name); } 函数的结构数组生成动态分配内存的有效方法,还是有更好的实践?

3 个答案:

答案 0 :(得分:1)

您的程序有几个错误,其中大多数错误与内存分配和内存泄漏有关。

例如,在函数construct中,为数据成员name

分配内存
    for(each=0; each<number; each++){
        person[each].name = (char*)malloc(sizeof(char));

然后在main中覆盖此值

person[0].name = "steven";
person[1].name = "michael";

因此,您无法再访问已分配的内存,也无法释放它。

至于这句话

free(&person[1]); 
然后你没有分开分配人[1]。您为结构的两个实例分配了一个范围。所以你可以只释放这个分配的范围。

你可以在函数构造中通过分配一个指向结构的指针数组来分别分配结构的每个实例。在这种情况下,函数将按以下方式显示

s_person ** construct( int number )
{
    int each;

    s_person **persons =  ( s_person ** ) malloc( number * sizeof( s_person * ) );

    if ( persons != NULL )
    {
        for ( each = 0; each < number; each++ )
        {
            persons[each] = ( s_person * )malloc( sizeof( s_person ) );
            if ( persons[each] != NULL )
            {
                persons[each]->name = ( char* )malloc( MAX_NAME );
            }
        }
    }

    return persons;
}

在main中,您必须使用标准C函数strcpy来初始化具有字符串文字的已分配结构的数据成员name

#include <string.h>

//...

int main( void )
//^^^^^^^^^^^^^^
{
    s_person **persons = construct( 2 );
    if ( persons[0] ) strcpy( persons[0]->name, "steven" );
    if ( persons[1] ) strcpy( persons[1]->name, "michael" );

    //...

在这种情况下,您可以删除每个单独的元素。例如

free( persons[0]->name );
free( persons[0] );
persons[0] = NULL;

free( persons[1]->name );
free( persons[1] );
persons[1] = NULL;

// and at last

free( persons );

答案 1 :(得分:0)

你不能释放一部分内存块。

在函数construct中,您将分配一个大小为sizeof(s_person) * number字节的内存区域。如果您尝试释放第一个元素,则释放整个内存(请注意&person[0]等于construct(2);返回的值。

如果您尝试释放&person[1],则尝试释放未知的内存区域,free(&person[1])将失败。释放无效/未知的内存区域不会导致崩溃。但是在您发布的代码中,您释放person的整个内存区域会导致访问冲突,从而导致person[1]的地址成为free的输入打电话。

如果你想释放单身人士,你可能想要使用linked lists而不是一个巨大的阵列...网上有很多例子。

我在您的代码中看到了另一个问题。查看您的函数construct我注意到您为persone的名称分配了一个字节(但我想您希望该名称最多包含MAX_NAME个字符)。因此,请将person[each].name = (char*)malloc(sizeof(char));修改为person[each].name = (char*)malloc(sizeof(char) * MAX_NAME);或将您的代码更改为以下内容:

#define MAX_NAME 50
typedef struct s_person {
    char name[MAX_NAME];
    double grade;
}s_person;

s_person* construct(int number){
    s_person *person = (s_person*)malloc(sizeof(s_person) * number);
    return person;
}

我建议使用后者,因为你不能忘记释放为每个人的名字分配的内存,这样可以更容易地使你的代码变得容易。

答案 2 :(得分:0)

为什么malloc personn你可以使用堆栈:

#include<stdio.h>                                                              
#include<stdlib.h>                                                             
#define MAX_NAME 50                                                            
typedef struct s_person {                                                      
    char *name;                                                                
    double grade;                                                              
}s_person;                                                                     


main()                                                                         
{                                                                              
    s_person person[2];                                                        
    person[0].name = "steven";                                                 
    person[1].name = "michael";                                                

    printf("%s %s\n", person[0].name, person[1].name);                         
}