我可以仅分配输入字符串所需的确切内存并指向它吗?

问题描述

我正在编写一个程序,其中将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*结构中使用node可以吗?我会冒险吗?

我听说过结构内部的灵活数组,但是我不想将数组直接放在结构内部,因为对于程序,我需要能够分离它,然后使用另一个指针指向它

解决方法

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.
,

出于您的目的,您必须分别分配node结构和行片段。

根据其余代码的假设,您可以只为每行的字符串分配空间,而不是为整个数组分配空间,但是必须更改node结构以使用char *t;而不是line 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;
}