结构体套指针问题
调试在 freeSpace里面报错,j =2 时运行在 if(ts->students!=NULL)报错。
感谢感谢感谢
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Teacher
{
char *name;
char **students;
}STS;
void test1(STS ***ts)
{
STS **teacher = malloc(sizeof(STS *)*3);
for(int i=0;i<3;i++)
{
// 给每一个老师开辟空间
teacher = malloc(sizeof(STS));
// 给老师姓名开辟空间
teacher->name = malloc(32);
// 给老师姓名赋值
sprintf(teacher->name,"teacher%d",i+1);
//给老师带的学生开辟空间
teacher->students = malloc(sizeof(char *)*5);
for(int j=0;j<5;j++)
{
//给老师 i 带的每个同学的姓名开辟空间
teacher->students = malloc(32);
// 给每个学生姓名赋值
sprintf(teacher->students,"%dstudent%d",i+1,j+1);
}
}
*ts = teacher;
}
void printfInformation(STS **teacher)
{
for(int i=0;i<3;i++)
{
printf("%s:\n",teacher->name);
for(int j=0;j<5;j++)
{
printf("\t%s\n",teacher->students);
}
}
return ;
}
void freeSpace(STS **ts) //-----------------------------------------------这里
{
if(ts==NULL)
{
return ;
}
for(int i=0;i<3;i++)
{
//释放老师的名字
if(ts->name!=0)
{
free(ts->name);
ts->name =NULL;
}
printf("teacher[%d]->name\n",i);
for(int j=0;j<5;j++)
{
// 释放学生的姓名
if(ts->students!=NULL)//--------------------------------第二次运行在这里报错
{
free(ts->students);
ts->students =NULL;
printf("\tteacher[%d]->students[%d]\n",i,j);
}
//释放学生
if(ts->students!=0)
{
free(ts->students);
ts->students = NULL;
printf("\tteacher[%d]->students\n",i);
}
}
//释放每一个老师
if(ts!=0)
{
free(ts);
ts =NULL;
}
}
free(ts);
ts =NULL;
}
int main()
{
STS ** ts =NULL;
test1(&ts); // 开辟空间 ,并赋值
printfInformation(ts); // 打印信息
freeSpace(ts); // err
ts =NULL;
return 0;
} #include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Teacher {
char *name;
char **students;
} STS;
void test1(STS ***ts) {
STS **teacher = malloc(sizeof(STS *) * 3);
for(int i = 0; i < 3; i++) {
// 给每一个老师开辟空间
teacher = malloc(sizeof(STS));
// 给老师姓名开辟空间
teacher->name = malloc(32);
// 给老师姓名赋值
sprintf(teacher->name, "teacher%d", i + 1);
// 给老师带的学生开辟空间
teacher->students = malloc(sizeof(char *) * 5);
for(int j = 0; j < 5; j++) {
// 给老师 i 带的每个同学的姓名开辟空间
teacher->students = malloc(32);
// 给每个学生姓名赋值
sprintf(teacher->students, "%dstudent%d", i + 1, j + 1);
}
}
*ts = teacher;
}
// 仔细看free的顺序是不是发现了一个规律?
// free的顺序正好和malloc的顺序相反
// 这样就一定不会出问题
void free_space(STS **ts) {
if(!ts) return;
for(size_t i = 0; i < 3; ++i) {
for(size_t j = 0; j < 5; ++j) {
free(ts->students);
}
free(ts->students);
free(ts->name);
free(ts);
}
free(ts);
}
void freeSpace(STS **ts) {
if(ts == NULL) return;
for(int i = 0; i < 3; i++) {
// 释放老师的名字
free(ts->name);
free(NULL); // 不会出问题,^_^
/*
//if(ts->name != 0) {
if(ts->name != NULL) { // 写成这样更好
// 其实可以不判断的
// free(NULL);
// 这么写没有任何问题
free(ts->name);
//ts->name = NULL; // 没有必要
}
*/
printf("teacher[%d]->name\n", i);
for(int j = 0; j < 5; j++) {
free(ts->students);
}
free(ts->students);
// 下面的代码有问题
/*
for(int j = 0; j < 5; j++) {
// 释放学生的姓名
if(ts->students != NULL) {
free(ts->students);
ts->students = NULL;
printf("\tteacher[%d]->students[%d]\n", i, j);
}
// 释放学生
if(ts->students != 0) {
free(ts->students);
ts->students = NULL;
printf("\tteacher[%d]->students\n", i);
}
}
*/
// 释放每一个老师
if(ts != 0) {
free(ts);
ts = NULL;
}
}
free(ts);
//ts = NULL; // 写这个同样多余,而且这里的这条语句还容易让人误解
// 反正我刚看到这里的时候就认为这里有问题,应该是 *ts = NULL;
// 但是通过进一步看代码,发现这里没有问题,写 *ts = NULL; 反而有问题
}
void printfInformation(STS **teacher) {
for(int i = 0; i < 3; i++) {
printf("%s:\n", teacher->name);
for(int j = 0; j < 5; j++) {
printf("\t%s\n", teacher->students);
}
}
return;
}
int main() {
STS **ts = NULL;
test1(&ts); // 开辟空间 ,并赋值
printfInformation(ts); // 打印信息
freeSpace(ts); // err
//free_space(ts);
//ts = NULL; // 我感觉没有必要,当然写上也不会有问题
// 这个可写可不写,我是不写的
// 我能保证这里不出问题
// 至少到目前为止,我还没有在这个位置出现过问题
// 我不写这个,我有这自信,^_^
return 0;
}
其实这个代码写的可以,就是你写代码的时候不是成对编写,这就导致嵌套的层数多了,就有可能出问题了
这里你把这个写到for循环里面了 free(ts->students);
如果成对编写,或者说照着申请内存的函数写释放内存的函数
就没问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Teacher
{
char *name;
char **students;
}STS;
void test1(STS ***ts)
{
STS **teacher = malloc(sizeof(STS *)*3);
for(int i=0;i<3;i++)
{
// 给每一个老师开辟空间
teacher = malloc(sizeof(STS));
// 给老师姓名开辟空间
teacher->name = malloc(32);
// 给老师姓名赋值
sprintf(teacher->name,"teacher%d",i+1);
//给老师带的学生开辟空间
teacher->students = malloc(sizeof(char *)*5);
for(int j=0;j<5;j++)
{
//给老师 i 带的每个同学的姓名开辟空间
teacher->students = malloc(32);
// 给每个学生姓名赋值
sprintf(teacher->students,"%dstudent%d",i+1,j+1);
}
}
*ts = teacher;
}
void printfInformation(STS **teacher)
{
for(int i=0;i<3;i++)
{
printf("%s:\n",teacher->name);
for(int j=0;j<5;j++)
{
printf("\t%s\n",teacher->students);
}
}
return ;
}
void freeSpace(STS **ts) //-----------------------------------------------这里
{
if(ts==NULL)
{
return ;
}
for(int i=0;i<3;i++)
{
//释放老师的名字
if(ts->name!=0)
{
free(ts->name);
ts->name =NULL;
}
printf("teacher[%d]->name\n",i);
for(int j=0;j<5;j++)
{
// 释放学生的姓名
if(ts->students!=NULL)//--------------------------------第二次运行在这里报错
{
free(ts->students);
ts->students =NULL;
printf("\tteacher[%d]->students[%d]\n",i,j);
}
// 就这里的问题
#if 0
//释放学生
if(ts->students!=0)
{
free(ts->students);
ts->students = NULL;
printf("\tteacher[%d]->students\n",i);
}
#endif
}
//释放学生
if(ts->students!=0)
{
free(ts->students);
ts->students = NULL;
printf("\tteacher[%d]->students\n",i);
}
//释放每一个老师
if(ts!=0)
{
free(ts);
ts =NULL;
}
}
free(ts);
ts =NULL;
}
int main()
{
STS ** ts =NULL;
test1(&ts); // 开辟空间 ,并赋值
printfInformation(ts); // 打印信息
freeSpace(ts); // err
ts =NULL;
return 0;
}
我要吐槽一下你写的这注释
// 给每一个老师开辟空间
// 释放每一个老师
// 给每一个teacher开辟空间
// 释放每一个teacher
我感觉有些单词还是不翻译的好,翻译成中文以后感觉怪怪的,^_^ 可以看出,这里我把 freeSpace 和 printfInformation 的顺序换了一下
就是为了写 freeSpace 函数的时候(或者说检查 freeSpace 函数的时候),方便对照申请内存的函数(这里的 test1)
内存怎么申请的就怎么释放,释放的顺序和申请的顺序相反,这样就不会有问题
人造人 发表于 2022-2-23 01:52
我要吐槽一下你写的这注释
// 给每一个老师开辟空间
// 释放每一个老师
{:10_257:}好好 人造人 发表于 2022-2-23 01:47
其实这个代码写的可以,就是你写代码的时候不是成对编写,这就导致嵌套的层数多了,就有可能出问题了
这里 ...
十分感谢{:10_281:}
页:
[1]