释放内存函数 C

Deallocated memory functions C

我在 C 中的内存释放有问题。没有功能划分一切都很好,但不幸的是它不适用于相同的功能。这是代码:

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

typedef struct {
    char *name;
    enum {
        summer,
        winter
    } index;
} student;

bool init(student *s) {
    printf("The next stage in the allocation of memory\n");
    s = (student*)malloc(sizeof(*s));
    if (&s == NULL) {
        printf("Allocation Failed\n");
        return 0;
    } else {
        printf("Allocation completed successfully\n");
    }
}   

void delete(student *s) {
    if (&s != NULL) {
        printf("begin removal\n");
        free(s);
        printf("Released memory");
    }
}

int main() {
    student *s;
    init(s);
    delete(s);

    return 0;
}

我不知道我做错了什么。请帮忙。

您永远不会更改 main 中的 s

解决方案 1:将指针传递给 main 中的变量,以便 init 进行填充。

void init_student(student** s_ptr) {
    *s_ptr = (student*)malloc(sizeof(student));
    if (*s_ptr == NULL) {
        fprintf(stderr "panic: Allocation Failed\n");
        exit(1);
    }

    (*s_ptr)->name = malloc(MAX_NAME_SIZE + 1);
    if ((*s_ptr)->name == NULL) {
        fprintf(stderr "panic: Allocation Failed\n");
        exit(1);
    }

    (*s_ptr)->name[0] = 0;

    (*s_ptr)->gpa = 0;
}   

void delete_student(student* s) {
    free(s->name);
    free(s);
}

int main() {
    student* s;
    init_student(&s);
    delete_student(s);
    return 0;
}

解决方案 1b:相同,但实现更简洁。

void init_student(student** s_ptr) {
    student* s = (student*)malloc(sizeof(student));
    if (*s_ptr == NULL) {
        fprintf(stderr "panic: Allocation Failed\n");
        exit(1);
    }

    s->name = malloc(MAX_NAME_SIZE + 1);
    if (s->name == NULL) {
        fprintf(stderr "panic: Allocation Failed\n");
        exit(1);
    }

    s->name[0] = 0;

    s->gpa = 0;

    *s_ptr = s;
}   

void delete_student(student* s) {
    free(s->name);
    free(s);
}

int main() {
    student* s;
    init_student(&s);
    delete_student(s);
    return 0;
}

解决方案 2:Return 分配点到 main

student* init_student() {
    student* s = (student*)malloc(sizeof(student));
    if (s == NULL) {
        fprintf(stderr "panic: Allocation Failed\n");
        exit(1);
    }

    s->name = malloc(MAX_NAME_SIZE + 1);
    if (s->name == NULL) {
        fprintf(stderr "panic: Allocation Failed\n");
        exit(1);
    }

    s->name[0] = 0;

    s->gpa = 0;

    return s;
}   

void delete_student(student* s) {
    free(s->name);
    free(s);
}

int main() {
    student* s = init_student();
    delete_student(s);
    return 0;
}

请注意,&s == NULL 永远不会为真,因为 &s 是变量本身的地址。您只想 s == NULL 检查 s.

中指针的值

首先,函数 init 有未定义的行为,因为它 returns 在内存分配成功的情况下什么都没有。

您可以通过返回指向已分配内存的指针或NULL来检查内存是否已分配。

还有这个说法

if(&s==NULL){

错了。由于局部变量 s 的地址不等于 NULL.

,因此条件总是会产生 false

所以函数可以改写成下面的方式

student * init()
{
    printf("The next stage in the allocation of memory\n");

    student *s = ( student* )malloc( sizeof( *s ) );

    if ( s == NULL )
    {
        printf("Allocation Failed\n");
    } 
    else 
    {
        printf("Allocation completed successfully\n");
    }

    return s;
} 

并称赞

int main( void )
          ^^^^^
{
    student *s = init();
    //...

或者可以这样定义

int init( student **s )
{
    printf("The next stage in the allocation of memory\n");

    *s = ( student* )malloc( sizeof( **s ) );

    int success = *s != NULL;

    if ( !success )
    {
        printf("Allocation Failed\n");
    } 
    else 
    {
        printf("Allocation completed successfully\n");
    }

    return success;
} 

并称赞

int main( void )
          ^^^^^
{
    student *s;
    init( &s );
    //...

函数 delete 至少应该像

那样定义
void delete(student *s) {
    if (s != NULL) {
       ^^^
        printf("begin removal\n");
        free(s);
        printf("Released memory");
    }
}

首先,free 是 NULL 安全的。如果变量已经是 NULL,基本上什么也不会发生。您不必检查它是否为 NULL。 (你可以查看第313页ISO-IEC 9899

另外,初始化student->name和分配时,会出现内存泄漏。你也必须释放它。

所以,你的删除功能可能是这样的;

  void delete(student *s) {
    printf("begin removal\n");
    free(s->name);
    free(s);
    printf("Released memory");
}

if (&s == NULL)是错误的。必须用 if (s == NULL).

更改它们

你的配置可能会在大代码中引起很大的麻烦。如果分配 s = (student*)malloc(sizeof(*s)); 则意味着 "allocate s with size of *s"。但是指针大小是固定的内存块(多为 8 个字节)。这意味着您阻塞了一定大小的内存。如果你有比这更大的结构,这种分配会破坏内存并且你的可执行文件将被 OS 杀死(你可以尝试向你的结构添加更多变量并初始化它们)。在小型结构和非常短的 运行 次中,大多数情况下这种分配也有效。但我保证这在 运行 时间内是不安全的。并且它不会在编译时给出任何警告或错误。真正的方法是s = malloc(sizeof(student))。通过这种方式,您可以准确地分配所有内存块。并且您的记忆在 运行 时间内保持安全。

最后,您的 init 函数应该 return 初始化变量。你的初始化函数可能是这样的;

#define NAME_LENGHT 128

...

student * init(student *s) {
   printf("The next stage in the allocation of memory\n");
   s = malloc(sizeof(student));
   if (s == NULL) {
       printf("Allocation Failed\n");
       return NULL;
   }

   s->name = malloc(NAME_LENGHT); 
   if (s->name == NULL) {
       printf("Allocation Failed\n");
       return NULL;
   } else {
       printf("Allocation completed successfully\n");
   }
   //alternatively you can strdup directly without any allocation
   // s->name = strdup("some name");
   return s; 
}