如何为具有未知变量大小成员的结构分配内存?

How to allocate memory for a struct with a member of unknown variable size?

几天前有人好心地帮助了我,其中很大一部分在另一个 中。那时候struct base的大小是事先知道的。我想将成员 path 更改为一个字符数组,直到在 base_new() 函数中为 base 的新实例分配内存之前才知道其大小。

之前的版本要求所有的文件都放在同一个目录下,只增加了文件名;并且它的长度限制为256。现在我想允许用户在../../databases目录下添加子目录并且不限制长度。

是否可以在base_new()中的db[i] = malloc( sizeof ( struct base ) )之前或之后设置path的大小?

或者,也许我应该简单地问一下,如何才能做到这一点?

谢谢。

/* Global declaration */
struct base {
 ...
 char path[];
};

struct base **db;

/* in main() */
db = malloc( n * sizeof *db );
for (size_t i = 0; i < n; ++i)
  db[i] = NULL;

/* Function to assign pointer db[i] to newly allocated struct base */
int base_new( void )
{
  /* declarations */
  // Assign pointer to beginning of memory allocation for the new instance of struct base.
  if ( ( db[i] = malloc( sizeof ( struct base ) ) ) == NULL )
    {
      printf( "Error attempting to malloc space for new base.\n" );
      return 1;
    }

  // When size of path was fixed, just truncated name to 256. */
  l = sizeof( db[i]->path );
  rc = snprintf( db[i]->path, l, "%s%.*s", "../../databases/", 256, name );
  if ( rc > l - 1 || rc < 0 )
    {
      // Not enough space; truncate and add the '[=10=]' at l.
      db[i]->path[l] = '[=10=]';
    }  

  // When size of path variable and writing path. */
  l = sizeof( db[i]->path ) - 16;
  rc = snprintf( db[i]->path, l, "%s%s", "../../databases/", path );
  if ( rc > l - 1 || rc < 0 )
    {
      
      db[i]->path[l] = '[=10=]';
    }  

}

我在问题顶部收到一条消息,询问是否有现有问题回答了这个问题。它密切相关且很有帮助,但我认为我在这里收到的答案更好,并讨论了其他一些相关点。我不知道它应该如何工作,但我选择了否,因为这个答案更好,或者至少我能更好地理解它。这个答案显示了如何 malloc 结构的变量成员,并讨论了在释放指向结构的指针之前按成员释放结构的内存。另一个问题有点笼统,但仍然有帮助。谢谢。

您可以在结构中使用指针代替数组:

struct base {
    ...
    char *path;
};

稍后,在需要时为该指针分配内存:

base.path = malloc(n * sizeof(char)); // n is the variable size you will set before

既然你现在动态分配内存,请不要忘记 free 以避免任何内存泄漏。在 C 中,要求每个结构都具有固定的字节长度,因此,例如 sizeof(struct base) 可以在编译时求值。在您的情况下,可变长度数组的大小无法在编译时确定,因此执行类似 char path[l] 的操作是非法的,其中 l 在编译时未知。

顺便说一句,关于

的更正
l = sizeof( db[i]->path );

首先,即使 path 被声明为一个数组,这不会给你它的长度方面的大小,它会 return 你完整的字节大小被数组占用,你得除以sizeof (char)得到长度。但是,既然您已将其声明为指针,我想您真的不需要这样做。