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



几天前,有人好心地帮我解决了另一个SO问题中的大部分问题。当时,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 '' at l.
db[i]->path[l] = '';
}  
// 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] = '';
}  
}

我在问题的顶部收到一条消息,询问现有问题是否回答了这个问题。这是密切相关和有用的,但我认为我在这里得到的答案更好,并讨论了其他一些相关的问题。我不知道它应该如何工作,但我选择了"否",因为这个答案更好,或者至少我能更好地理解它。这个答案显示了如何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在编译时未知。

Btw,关于的校正

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

首先,即使path被声明为数组,这也不会根据它的长度给出它的大小,它会返回数组占用的完整字节大小,你必须将其除以sizeof (char)才能得到长度。然而,既然您已经将其声明为指针,我想您实际上不需要这样做。

最新更新