几天前,有人好心地帮我解决了另一个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)
才能得到长度。然而,既然您已经将其声明为指针,我想您实际上不需要这样做。