Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C语言中释放内存_C_Pointers_Memory Leaks - Fatal编程技术网

在C语言中释放内存

在C语言中释放内存,c,pointers,memory-leaks,C,Pointers,Memory Leaks,我对这个小程序有问题: 已更新(根据一些请求,我已将所有内容都包含在这里,以便明确我在做什么。很抱歉时间太长): Student.h文件: typedef struct Student { char *name; int age; char *major; char *toString; } *Student; extern Student newStudent(char *name, int age, char *major); static void error(ch

我对这个小程序有问题:

已更新(根据一些请求,我已将所有内容都包含在这里,以便明确我在做什么。很抱歉时间太长): Student.h文件:

typedef struct Student {
  char *name;
  int age;
  char *major;
    char *toString;
} *Student;

extern Student newStudent(char *name, int age, char *major);
static void error(char *s) {
  fprintf(stderr,"%s:%d %s\n",__FILE__,__LINE__,s);
  exit(1);
}

static StudentList alloc(StudentList students, Student student) {

  StudentList p;
    if (!(p=(StudentList)malloc(sizeof(*p)))){
    error("out of memory");}
  p->student=student;
  p->students=students;
  return p;
}

extern Students newStudents() {
  Students p;
    if (!(p=(Students)malloc(sizeof(*p)))){
    error("out of memory");
    }
  p->cursor=0;
  p->students=0;
  return p;
}

extern void addStudent(Students students, Student student) {
  StudentList p=students->students;
  if (!p) {
    students->students=alloc(0,student);

    return;
  }
while (p->students)
     p=p->students;
  p->students=alloc(0,student); 
    }    

extern void initStudent(Students students) {
  students->cursor=students->students;
}

extern Student currStudent(Students students) {
  StudentList cursor=students->cursor;
  if (!cursor)
    return 0;
  return cursor->student;
}

extern void nextStudent(Students students) {
  students->cursor=students->cursor->students;
}
int main() {
  Students students=newStudents();
  addStudent(students,newStudent("Julie",22,"CS"));
  addStudent(students,newStudent("Trevor",32,"EE"));

  for (initStudent(students);
       currStudent(students);
       nextStudent(students)) {
      char *line=currStudent(students)->toString;
    printf("%s\n",line);
      free(currStudent(students));
    free(line);
  }

    free(students->students);
    free(students);
  return 0;
}
Student.c文件: c

和我的主要方法:

typedef struct Student {
  char *name;
  int age;
  char *major;
    char *toString;
} *Student;

extern Student newStudent(char *name, int age, char *major);
static void error(char *s) {
  fprintf(stderr,"%s:%d %s\n",__FILE__,__LINE__,s);
  exit(1);
}

static StudentList alloc(StudentList students, Student student) {

  StudentList p;
    if (!(p=(StudentList)malloc(sizeof(*p)))){
    error("out of memory");}
  p->student=student;
  p->students=students;
  return p;
}

extern Students newStudents() {
  Students p;
    if (!(p=(Students)malloc(sizeof(*p)))){
    error("out of memory");
    }
  p->cursor=0;
  p->students=0;
  return p;
}

extern void addStudent(Students students, Student student) {
  StudentList p=students->students;
  if (!p) {
    students->students=alloc(0,student);

    return;
  }
while (p->students)
     p=p->students;
  p->students=alloc(0,student); 
    }    

extern void initStudent(Students students) {
  students->cursor=students->students;
}

extern Student currStudent(Students students) {
  StudentList cursor=students->cursor;
  if (!cursor)
    return 0;
  return cursor->student;
}

extern void nextStudent(Students students) {
  students->cursor=students->cursor->students;
}
int main() {
  Students students=newStudents();
  addStudent(students,newStudent("Julie",22,"CS"));
  addStudent(students,newStudent("Trevor",32,"EE"));

  for (initStudent(students);
       currStudent(students);
       nextStudent(students)) {
      char *line=currStudent(students)->toString;
    printf("%s\n",line);
      free(currStudent(students));
    free(line);
  }

    free(students->students);
    free(students);
  return 0;
}
我正在使用valgrind检查内存泄漏,出现以下错误:

8 bytes in 1 blocks are definitely lost in loss record 1 of 1
==9520==    at 0x40054E5: malloc (vg_replace_malloc.c:149)
==9520==    by 0x8048908: alloc (Students.c:13)
==9520==    by 0x80489EB: addStudent (Students.c:42)
==9520==    by 0x804882E: main (StudentList.c:10)

我知道我需要在alloc函数中释放分配给p的内存,但是我应该在哪里调用free(p)?还是我做错了什么?请帮忙

我想你的alloc有问题

如果你想要一个指针,它应该是

StudentList *p;
p = (StudentList*)malloc(sizeof(StudentList));

我想你的alloc有问题

如果你想要一个指针,它应该是

StudentList *p;
p = (StudentList*)malloc(sizeof(StudentList));

如果我使用malloc(),我不会将sizeof与变量一起使用。您应该使用
malloc(n*sizeof(StudentList))
。话虽如此

你有一些主要的顾虑。首先,你没有告诉我们学生和学生名单的具体定义。在某些情况下,当我认为你的意思是NULL时,你会传递0,当你的意思是NULL时,千万不要使用0。如果malloc()失败——也就是说,它返回NULL——那么就不会对结果调用free()。永远,永远自由

您应该只释放(a)已成功分配的内存块,以及(b)不再需要的内存块。这似乎并没有输入到您的代码中


还有其他问题(当您初始化p时,您假设addStudent中的student为非NULL),但它们并没有完全解决您关于free()用法的问题。

如果使用malloc(),我不会将sizeof与变量一起使用。您应该使用
malloc(n*sizeof(StudentList))
。话虽如此

你有一些主要的顾虑。首先,你没有告诉我们学生和学生名单的具体定义。在某些情况下,当我认为你的意思是NULL时,你会传递0,当你的意思是NULL时,千万不要使用0。如果malloc()失败——也就是说,它返回NULL——那么就不会对结果调用free()。永远,永远自由

您应该只释放(a)已成功分配的内存块,以及(b)不再需要的内存块。这似乎并没有输入到您的代码中

还有其他问题(您在初始化p时假设addStudent中的student为非NULL),但它们并没有完全解决您关于free()用法的问题。

这是做什么的:

if (!(p=(StudentList)malloc(sizeof(*p)))){
    free(p);
因此,如果
p
无法分配,请释放它?

这是做什么的:

if (!(p=(StudentList)malloc(sizeof(*p)))){
    free(p);

因此,如果
p
无法分配,请释放它?

问题是,当你完成了
学生
学生名单
并且不再需要它时,你会怎么做。在这一点上,您应该调用
free()
,以获取该结构中分配的所有内容


您可能需要一个
freeStudents
函数,该函数遍历学生列表并释放其中的所有
Student
s和所有
StudentList
项。然后,每当你想删除一个学生列表时,就调用该函数。

问题是,当你完成了一个
学生
学生列表
并且不再需要它时,你该怎么做。在这一点上,您应该调用
free()
,以获取该结构中分配的所有内容


您可能需要一个
freeStudents
函数,该函数遍历学生列表并释放其中的所有
Student
s和所有
StudentList
项。然后,只要您想删除学生列表,就可以调用该函数。

我假设StudentList的类型定义为指向学生的某种类型的指针。在这种情况下,alloc函数中的这一行是一个问题。
p=(学生名单)malloc(sizeof(*p))


您试图在分配指针之前取消对其的引用,这是不好的。

我假设StudentList的类型定义为指向Student的某种类型的指针。在这种情况下,alloc函数中的这一行是一个问题。
p=(学生名单)malloc(sizeof(*p))


您试图在分配指针之前解除对它的引用,这是不好的。

当您不再需要使用已分配的对象时,应该释放内存

什么是
StudentList
Student
?在我看来,您的数据结构构造不正确。为什么您的
StudentList
存储指向另一个
StudentList
的指针?您可能应该使用
malloc
创建
StudentList
,并使用
newStudents
函数返回指向该StudentList的指针,而不是使用
addStudent
中的旧StudentList结构的副本返回新的StudentList结构,只需修改最初创建的结构即可

所以会是这样的:

StudentList *newStudentList() {
    //malloc a new StudentList and return the pointer
}
void freeStudentList(StudentList *list) {
    //free the list pointer and all its child resources (i.e. the students in the list)
}
Student *newStudent(const char *name, etc) {
    //malloc a new Student and return the pointer
}
void addStudentToList(StudentList *list, Student *student) {
    //modify the StudentList which has been passed in by adding the student to it.
}
Students newStudents()
{
  Students p;
  // ...
  return p;
}
Students p = students;
while (p)
{
  Students next = p->students;
  free (p);
  p = next;
}

如果您不打算单独使用newStudent和addStudent,您可以将newStudent合并到addStudent中;如果您还打算单独使用freeStudent和removeStudentFromList,则可能需要使用freeStudent和removeStudentFromList函数。你应该看看Google,看看C语言中动态数据结构的例子(这是Google上的第一个结果,但还有很多其他结果)。

当你不再需要使用分配的对象时,你应该释放内存

什么是
StudentList
Student
?在我看来,您的数据结构构造不正确。为什么您的
StudentList
存储指向另一个
StudentList
的指针?您可能应该使用
malloc
创建
StudentList
,并使用
newStudents
函数返回指向该结构的指针,而不是在
addStudent
中返回包含旧结构副本的新StudentList结构,只需修改即可