如何在C中动态分配内存并确定数组大小?
发布时间:2020-12-16 10:27:52 所属栏目:百科 来源:网络整理
导读:我试图从 python背景教自己C.我目前的小问题是尝试对数组长度等内容进行较少的硬编码,并根据输入动态分配内存. 我写了以下程序.我希望社区的建议可以通过以下方式进行修改: 1.)使第一个和最后一个名称元素变长.目前,他们的长度被硬编码为MAX_NAME_LENGTH.这
我试图从
python背景教自己C.我目前的小问题是尝试对数组长度等内容进行较少的硬编码,并根据输入动态分配内存.
我写了以下程序.我希望社区的建议可以通过以下方式进行修改: 1.)使第一个和最后一个名称元素变长.目前,他们的长度被硬编码为MAX_NAME_LENGTH.这将涉及更改Names structdeclaration以及我为其元素分配值的方式. 2.)Bonus:找出一些方法来逐步向name_list数组中添加新元素,而无需事先确定其长度.基本上使它成为可扩展的列表. /* namelist.c Loads up a list of names from a file to then do something with them. */ #include <stdlib.h> #include <stdio.h> #include <memory.h> #define DATAFILE "name_list.txt" #define DATAFILE_FORMAT "%[^,]%*c%[^n]%*c" #define MAX_NAME_LENGTH 100 typedef struct { char first[MAX_NAME_LENGTH]; char last[MAX_NAME_LENGTH]; } Name; int main() { FILE *fp = fopen(DATAFILE,"r"); // Get the number of names in DATAFILE at runtime. Name aName; int lc = 0; while ((fscanf(fp,DATAFILE_FORMAT,aName.last,aName.first))!=EOF) lc++; Name *name_list[lc]; // Now actually pull the data out of the file rewind(fp); int n = 0; while ((fscanf(fp,aName.first))!=EOF) { Name *newName = malloc(sizeof(Name)); if (newName == NULL) { puts("Warning: Was not able to allocate memory for ``Name`` ``newName``on the heap."); } memcpy(newName,&aName,sizeof(Name)); name_list[n] = newName; n++; } int i = 1; for (--n; n >= 0; n--,i++) { printf("%d: %s %sn",i,name_list[n]->first,name_list[n]->last); free(name_list[n]); name_list[n] = NULL; } fclose(fp); return 0; } name_list.txt的示例内容: Washington,George Adams,John Jefferson,Thomas Madison,James 更新1: 我已经实现了链接列表和@Williham建议的一些辅助函数,结果如下. #include <stdlib.h> #include <stdio.h> #include <string.h> #define DATAFILE "name_list.txt" #define MAX_NAME_LENGTH 30 #define DATAFILE_FORMAT "%29[^,]%*c%29[^n]%*c" static const int INPUT_BUFFER_SIZE_DEFAULT = sizeof(char) * MAX_NAME_LENGTH; typedef struct _Name Name; struct _Name { char *first; char *last; Name *next; }; int get_charcount(char *str); Name * create_name_list(char *filename); void print_name_list(Name *name); void free_name_list (Name *name); int main() { // Read a list of names into memory and // return the head of the linked list. Name *head = create_name_list(DATAFILE); // Now do something with all this data. print_name_list(head); // If you love something,let it go. free_name_list(head); head = NULL; return 0; } int get_charcount (char *str) { int input_length = 1; while (str[input_length] != ' ') { input_length++; } return input_length; } Name * create_name_list(char *filename) { FILE *fp = fopen(DATAFILE,"r"); char *first_input_buffer = malloc(INPUT_BUFFER_SIZE_DEFAULT); char *last_input_buffer = malloc(INPUT_BUFFER_SIZE_DEFAULT); Name *firstNamePtr; Name *previousNamePtr; while ((fscanf(fp,last_input_buffer,first_input_buffer))!=EOF) { Name *newNamePtr = malloc(sizeof(Name)); if (previousNamePtr) { previousNamePtr->next = newNamePtr; previousNamePtr = newNamePtr; } else { firstNamePtr = previousNamePtr = newNamePtr; } char *temp_buffer = malloc(get_charcount(first_input_buffer)); strcpy(temp_buffer,first_input_buffer); newNamePtr->first = malloc(get_charcount(first_input_buffer)); strcpy(newNamePtr->first,temp_buffer); realloc(temp_buffer,get_charcount(last_input_buffer)); strcpy(temp_buffer,last_input_buffer); newNamePtr->last = malloc(get_charcount(last_input_buffer)); strcpy(newNamePtr->last,temp_buffer); free(temp_buffer); temp_buffer = NULL; } previousNamePtr->next = NULL; previousNamePtr = NULL; free(first_input_buffer); free(last_input_buffer); first_input_buffer = NULL; last_input_buffer = NULL; fclose(fp); return firstNamePtr; } void print_name_list (Name *name) { static int first_iteration = 1; if (first_iteration) { printf("nList of Namesn"); printf("=============n"); first_iteration--; } printf("%s %sn",name->first,name->last); if (name->next) print_name_list(name->next); else printf("n"); } void free_name_list (Name *name) { if (name->next) free_name_list(name->next); free(name->first); free(name->last); name->first = NULL; name->last = NULL; name->next = NULL; free(name); name = NULL; } 解决方法
一个非常简单的方法是根本不使用数组,而是使用链表:
这可以通过多种方式完成,但最简单的可能是修改Name结构,如下所示: typedef struct _Name Name; struct _Name { char *first; char *last; Name *next; }; 使用char *而不是char []将需要一些strcpying,但这实际上既不是在这里也不是在那里.要扩展数组,您现在可以一次一个地对这些元素进行malloc;然后适当地设置. 注意:在创建新的尾部元素时,请记住在NULL旁边设置. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |