如何为具有未知变量大小成员的结构分配内存?
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)
得到长度。但是,既然您已将其声明为指针,我想您真的不需要这样做。
几天前有人好心地帮助了我,其中很大一部分在另一个 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)
得到长度。但是,既然您已将其声明为指针,我想您真的不需要这样做。