释放内存函数 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;
}
我在 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
.
所以函数可以改写成下面的方式
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;
}