不使用 realloc 动态扩展 C 代码
Dynamically expanding C code without using realloc
我需要将文本中用逗号分隔的名称放入动态扩展的结构中,但我被禁止使用 realloc ()。我在这段代码中遇到核心转储错误。这段代码有什么错误?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct movie{
double budget;
int genre;
char* name;
double score;
int year;
};
void recorder_function(struct movie *movies){
FILE*fp;
fp=fopen("Movies.txt","r");
struct movie *p;
int i,n=0;
char line[1000];
char temp_budget[50];
char temp_name[50];
char temp_genre[50];
while (!feof(fp)) {
fgets(line,1000,fp);
sscanf(line,"%50[^,],%50[^,],%50[^,]",temp_budget,temp_genre,temp_name);
//I open the fields in this section
movies=(struct movie *)calloc(n+1,sizeof(struct movie));
p=(struct movie *)calloc(n+1,sizeof(struct movie));
p[n].name=(char*)malloc(sizeof(char)*(strlen(temp_name)+1));
movies[n].name=(char*)malloc(sizeof(char)*(strlen(temp_name)+1));
for(i=0;i<n;i++)
movies[i]=p[i];
strcpy(movies[n].name,temp_name);
free(p);
p=movies;
n++;
}
for(i=0;i<n;i++)
printf("%s\n",movies[i].name);
}
int main(){
int choice;
struct movie *movies;
recorder_function(movies);
}
用新分配的干净缓冲区覆盖指针 movie
是个坏主意。
相反,你应该
- 仅为
p
分配新缓冲区。
- 将新元素放入
p[n]
- 将现有元素
movie[0], ... , movie[n-1]
放入 p[0], ... , p[n-1]
- 释放旧缓冲区
movie
- 将新缓冲区
p
分配给 movie
不要忘记初始化movie
以免在第一次释放时造成麻烦。
此外 while (!feof(fp))
是 wrong,您应该在尝试读取之后和使用读取的内容之前检查读取是否成功。
更重要的一点是,您应该确保fopen()
成功。将 NULL
(失败时 fopen()
returns)传递给其他文件操作函数可能会导致麻烦。
另一点是用于 sscanf()
输出的数组应该有一个更多的元素作为终止空字符。
还有一点就是malloc()
家族的选角结果是considered as a bad practice.
试试这个:
void recorder_function(struct movie *movies){
FILE*fp;
fp=fopen("Movies.txt","r");
if(fp==NULL){
fputs("file open error\n", stderr);
return;
}
struct movie *p;
int i,n=0;
char line[1000];
char temp_budget[51];
char temp_name[51];
char temp_genre[51];
movies=NULL;
while (fgets(line,1000,fp)) {
sscanf(line,"%50[^,],%50[^,],%50[^,]",temp_budget,temp_genre,temp_name);
//I open the fields in this section
p=calloc(n+1,sizeof(struct movie));
p[n].name=malloc(sizeof(char)*(strlen(temp_name)+1));
strcpy(p[n].name,temp_name);
for(i=0;i<n;i++){
p[i]=movies[i];
}
free(movies);
movies=p;
n++;
}
for(i=0;i<n;i++){
printf("%s\n",movies[i].name);
}
}
下一阶段将修复参数 movie
的奇怪用法。 C 中的参数是所传递内容的 副本 ,被调用函数中参数的修改不会影响调用者中传递的内容。您的选择是:
- 删除参数
movies
并将其转换为局部变量。
- 让
recorder_function
获取指向 struct movie*
(struct movie**
) 的指针,并让它使用指针修改调用者指定的内容。 (在这种情况下,您还必须更改调用函数以传递指针的语句)
我需要将文本中用逗号分隔的名称放入动态扩展的结构中,但我被禁止使用 realloc ()。我在这段代码中遇到核心转储错误。这段代码有什么错误?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct movie{
double budget;
int genre;
char* name;
double score;
int year;
};
void recorder_function(struct movie *movies){
FILE*fp;
fp=fopen("Movies.txt","r");
struct movie *p;
int i,n=0;
char line[1000];
char temp_budget[50];
char temp_name[50];
char temp_genre[50];
while (!feof(fp)) {
fgets(line,1000,fp);
sscanf(line,"%50[^,],%50[^,],%50[^,]",temp_budget,temp_genre,temp_name);
//I open the fields in this section
movies=(struct movie *)calloc(n+1,sizeof(struct movie));
p=(struct movie *)calloc(n+1,sizeof(struct movie));
p[n].name=(char*)malloc(sizeof(char)*(strlen(temp_name)+1));
movies[n].name=(char*)malloc(sizeof(char)*(strlen(temp_name)+1));
for(i=0;i<n;i++)
movies[i]=p[i];
strcpy(movies[n].name,temp_name);
free(p);
p=movies;
n++;
}
for(i=0;i<n;i++)
printf("%s\n",movies[i].name);
}
int main(){
int choice;
struct movie *movies;
recorder_function(movies);
}
用新分配的干净缓冲区覆盖指针 movie
是个坏主意。
相反,你应该
- 仅为
p
分配新缓冲区。 - 将新元素放入
p[n]
- 将现有元素
movie[0], ... , movie[n-1]
放入p[0], ... , p[n-1]
- 释放旧缓冲区
movie
- 将新缓冲区
p
分配给movie
不要忘记初始化movie
以免在第一次释放时造成麻烦。
此外 while (!feof(fp))
是 wrong,您应该在尝试读取之后和使用读取的内容之前检查读取是否成功。
更重要的一点是,您应该确保fopen()
成功。将 NULL
(失败时 fopen()
returns)传递给其他文件操作函数可能会导致麻烦。
另一点是用于 sscanf()
输出的数组应该有一个更多的元素作为终止空字符。
还有一点就是malloc()
家族的选角结果是considered as a bad practice.
试试这个:
void recorder_function(struct movie *movies){
FILE*fp;
fp=fopen("Movies.txt","r");
if(fp==NULL){
fputs("file open error\n", stderr);
return;
}
struct movie *p;
int i,n=0;
char line[1000];
char temp_budget[51];
char temp_name[51];
char temp_genre[51];
movies=NULL;
while (fgets(line,1000,fp)) {
sscanf(line,"%50[^,],%50[^,],%50[^,]",temp_budget,temp_genre,temp_name);
//I open the fields in this section
p=calloc(n+1,sizeof(struct movie));
p[n].name=malloc(sizeof(char)*(strlen(temp_name)+1));
strcpy(p[n].name,temp_name);
for(i=0;i<n;i++){
p[i]=movies[i];
}
free(movies);
movies=p;
n++;
}
for(i=0;i<n;i++){
printf("%s\n",movies[i].name);
}
}
下一阶段将修复参数 movie
的奇怪用法。 C 中的参数是所传递内容的 副本 ,被调用函数中参数的修改不会影响调用者中传递的内容。您的选择是:
- 删除参数
movies
并将其转换为局部变量。 - 让
recorder_function
获取指向struct movie*
(struct movie**
) 的指针,并让它使用指针修改调用者指定的内容。 (在这种情况下,您还必须更改调用函数以传递指针的语句)