如何解决使用malloc
在C中如何为这些结构使用malloc()
typedef struct {
char *Name;
char *Email;
} Person;
typedef struct {
unsigned int len;
Value *pVal;
} Person;
如何使用fread()
读取这些结构的值?
Person *p;
p->pVal = (Value *)malloc(p->len * sizeof(Value));
p->pVal.Name = (char *)malloc(sizeof(char));
p->pVal.Email = (char *)malloc(sizeof(char));
这是正确的方法吗? Name
和Email
的大小将从文件中读取,并且大小可变。
解决方法
如果您不知道字符串的长度,则必须读取一些临时缓冲区,然后解析内容。
为字段定义一些最大长度会很有用:
// TODO: Check for NULL result for all calls to malloc
#define MAX_FIELD_LEN 500
char temp_name[MAX_FIELD_LEN] = {0};
char temp_email[MAX_FIELD_LEN] = {0};
Person *p = malloc(sizeof (*p));
p->len = ...;
p->pVal = malloc(p->len * sizeof(*p->pVal));
for (int i = 0; i < p->len; i++) {
// read file content into temp_name and temp_email
p->pVal[i].Name = malloc(strlen(temp_name)+1);
strcpy(p->pVal[i].Name,temp_name);
p->pVal[i].EMail = malloc(strlen(temp_email)+1);
strcpy(p->pVal[i].Email,temp_email);
}
这是基于您问题中的代码。没有更多有关如何获取数据的详细信息,就无法提供最佳解决方案。
您需要定义文件的结构。必须定义如何存储字符串以及在回读时如何分隔字符串。
您可以阅读有关“序列化/反序列化”的更多信息。
,您的代码中有错别字:第一种类型应该是Value
,而不是Person
:
typedef struct {
char *Name;
char *Email;
} Value;
typedef struct {
unsigned int len;
Value *pVal;
} Person;
要从堆中分配结构,可以使用malloc()
和提供要分配的对象的字节大小:
Person *p = malloc(sizeof(Person));
请注意,您可以从指针类型获得适当的大小,因此可以对所有类型使用更通用的语法:
Person *p = malloc(sizeof(*p));
pVal
指针似乎指向Value
结构的数组,因此您的分配是正确的,但是len
成员必须初始化为适当数量的元素。您还可以编写:
p->len = count;
p->pVal = malloc(p->len * sizeof(*p->pVal));
malloc()
分配的内存块未初始化,因此您必须手动将所有成员初始化为适当的值,或者使用calloc()
返回已初始化为所有位0的内存块,所有现代系统都意味着将所有成员初始化为0值:0
的整数成员,0.0
的浮点成员和NULL
的指针:
p->len = count;
p->pVal = calloc(p->len,sizeof(*p->pVal)); // members Name and Email are set to NULL
还要注意,C标准未指定对0字节的分配请求是返回空指针还是指向大小为零的对象的指针。您应该避免分配零字节:
p->len = count;
if (p->len == 0) {
p->pVal = NULL;
} else {
p->pVal = calloc(p->len,sizeof(*p->pVal)); // members Name and Email are set to NULL
}
还要注意,任何分配尝试都可能失败并返回空指针,因此您应该测试返回值并妥善处理分配失败。
对于可变大小的字符串,可以使用fgets()
读取文件,并使用strdup()
来分配字符串的副本:
char Name[100];
char Email[100];
if (fgets(Name,sizeof Name,fp) != NULL &&
fgets(Email,sizeof Email,fp) != NULL) {
Name[strcspn(Name,"\n")] = '\0'; // strip the trailing newline
Email[strcspn(Email,"\n")] = '\0'; // strip the trailing newline
p->pVal->Name = strdup(Name);
p->pVal->Email = strdup(Email);
} else {
/* handle invalid input */
}
这是一个结合以上内容以从文件中读取记录的功能:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char *Name;
char *Email;
} Value;
typedef struct {
unsigned int len;
Value *pVal;
} Person;
Person *read_person(FILE *fp,int count) {
Person *p = malloc(sizeof(*p));
if (p == NULL)
return NULL;
p->len = count;
if (p->len == 0) {
p->pVal = NULL;
} else {
p->pVal = calloc(p->len,sizeof(*p->pVal)); // members Name and Email are set to NULL
if (p->pVal == NULL) {
free(p);
return NULL;
}
for (unsigned int i = 0; i < len; i++) {
char Name[100];
char Email[100];
if (fgets(Name,fp) != NULL &&
fgets(Email,fp) != NULL) {
Name[strcspn(Name,"\n")] = '\0'; // strip the trailing newline
Email[strcspn(Email,"\n")] = '\0'; // strip the trailing newline
p->pVal[i].Name = strdup(Name);
p->pVal[i].Email = strdup(Email);
} else {
/* handle invalid input */
while (i-- > 0) {
free(p->pVal[i].Name);
free(p->pVal[i].Email);
}
free(p->pVal);
free(p);
return NULL;
}
}
}
return p;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。