C 我可以只调用输入字符串所需的确切内存并指向它吗?
我正在制作一个程序,将C 我可以只调用输入字符串所需的确切内存并指向它吗?,c,pointers,malloc,C,Pointers,Malloc,我正在制作一个程序,将fgets中的输入字符串保存在一个列表中,它们有固定的最大长度,但也可以更短;我这样保存它们: typedef char line[LINE_SIZE]; struct node{ line *t; //pointer and not just a variable so I can "detach" the allocation to do stuff struct node *prev; struct node
fgets
中的输入字符串保存在一个列表中,它们有固定的最大长度,但也可以更短;我这样保存它们:
typedef char line[LINE_SIZE];
struct node{
line *t; //pointer and not just a variable so I can "detach" the allocation to do stuff
struct node *prev;
struct node *next;
};
但是,在我的程序中,我只做了malloc(sizeof(line))
,这是一个具有最大固定长度的数组
我的问题是,如果我要分配像malloc(strlen(str)+sizeof((char)'\0'))
这样的东西来精确地只使用所需的内存,我如何指出它
在节点
结构中使用char*
可以吗?我会冒险吗
我听说过结构中的灵活数组,但我不想将数组直接放在结构中,因为对于程序,我需要能够分离它,然后用另一个指针指向它。malloc()
返回它分配的地址,您可以将返回值分配给一个变量并指向它。即使变量是结构的同一成员,也不需要总是分配最大或相同大小的内存
char* line=malloc(strlen(str)+1); // +1 for null terminate
strcpy(line, "This is a str"); // points the memory of returned
在结构中使用char*
是绝对好的。请将struct的成员视为普通变量
struct node
{
char* t;
struct node* prev;
struct node* next;
}
node n;
n.t = malloc(strlen(str) + 1); // it's fine.
strcpy(n.t, "This is a node"); // using the memory you allocated above
n.prev = n.next = NULL;
... // doing some processing
free(n.t); // don't forget to call free() when you're done using the memory.
出于您的目的,必须分别分配
节点
结构和行片段
根据代码其余部分的假设,您可以只为每行的字符串分配空间,而不是整个数组,但必须更改节点
结构以使用char*t代码>而不是行
typedef。注意,typedef数组非常容易混淆
唯一需要注意的是,在修改这些字符串时必须小心,因为不能在末尾添加任何字符,也不能通过将内容移动到超出其分配长度来插入任何字符。根据经验,如果您在修改这些字符串时重新分配它们,您应该是安全的
下面是一个简单的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char *t; //pointer and not just a variable so I can "detach" the allocation to do stuff
struct node *prev;
struct node *next;
};
struct node *read_file(FILE *fp) {
char buf[128];
struct node *head = NULL, tail = NULL, *n = NULL;
while (fgets(buf, sizeof buf, fp)) {
buf[strcspn(buf, "\n")] = '\0'; // strip the trailing newline if present
n = malloc(sizeof(*n));
if (n == NULL)
abort();
n->prev = tail;
n->next = NULL;
n->t = strdup(buf);
if (n->t == NULL)
abort();
if (tail == NULL) {
head = n;
} else {
tail->next = n;
}
tail = n;
}
return head;
}
#包括
#包括
#包括
结构节点{
char*t;//指针,而不仅仅是一个变量,这样我就可以“分离”分配来做一些事情
结构节点*prev;
结构节点*下一步;
};
结构节点*读取文件(文件*fp){
char-buf[128];
结构节点*head=NULL,tail=NULL,*n=NULL;
而(fgets(buf、sizeof buf、fp)){
buf[strcspn(buf,“\n”)]='\0';//如果存在尾随换行符,则将其去掉
n=malloc(sizeof(*n));
如果(n==NULL)
中止();
n->prev=尾部;
n->next=NULL;
n->t=strdup(buf);
如果(n->t==NULL)
中止();
if(tail==NULL){
水头=n;
}否则{
tail->next=n;
}
尾=n;
}
回流头;
}
根据定义sizeof((char)'\0')
=sizeof(char)
=1
,所以不要把它搞砸了。。。只保留malloc(strlen(str)+1)
并且在POSIX平台上,您可以使用您确定不想看到我在同一个调用中分配节点和线路吗?如果您在同一块中分配节点和线路,您以后无法单独释放线路,因此,您无法分离线并用其他块替换它,因为您不知道如何或何时释放它。