Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 我可以只调用输入字符串所需的确切内存并指向它吗?_C_Pointers_Malloc - Fatal编程技术网

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平台上,您可以使用您确定不想看到我在同一个调用中分配节点和线路吗?如果您在同一块中分配节点和线路,您以后无法单独释放线路,因此,您无法分离线并用其他块替换它,因为您不知道如何或何时释放它。