我正在编写一个函数,在其中我需要多次调用malloc,以便动态地为非常小的数组(如4-5个ints )分配内存。组合和长度在运行时确定)。这些数组用于存储不同类型的数据类型。因此,我想分配一个大内存,并使用它的所有类型。这就是我想要做的。
#include <stdio.h>
#include <stdlib.h>
int main() {
size_t n_char = 4, n_float =4 ; /* these are not fixed.
I set this just for demonstrative purposes,
n_char and n_float value are determined
during runtime */
char * a = malloc( n_char*sizeof(char) + n_float*sizeof(float) ); /* Allocating for 4 ints and 4 chars*/
for (int i=0; i<4 ; ++i) a[i] = 'a' ;
float *b = (void *)(a+4) ; /* can we cast this pointer in this way ?*/
for (int i=0; i<4 ; ++i) b[i] = 1.0f ;
for (int i=0; i<4 ; ++i) printf("%c" , a[i]) ;
printf("\n");
for (int i=0; i<4 ; ++i) printf("%f " , (double)b[i]) ;
printf("\n");
return 0;
}我现在很困惑,这是否一个好的允许的做法?
发布于 2022-08-07 09:34:28
这不一定是一个很好的实践,因为您不仅需要关心b的大小,还需要关注它的对齐需求。假设您只需要两个字符,并且使用了此代码,那么您的浮点数将在所有当前公共平台上不正确地对齐。
如果您知道编译期间的大小,只需分配一个结构:
struct foo {
char c[4];
float f[4];
}编译器会处理剩下的。否则,如果是动态的,而char数组是6个元素,则需要将该6整到alignof(float)的最接近的倍数(最有可能是8)。当然,您也需要分配足够的内存,即不需要数组元素的和,但也要考虑填充,例如,假设您分配了6个字符,6个浮点数,您可能会得到6个字符,2个填充字节,6*4个字节。
转换本身被认为是合法的,指针算法也是合法的,因为所有这些都指向没有有效类型的分配数组。
另一种不用担心alignof的方法是先放置float数组-- alignof(char)将是1,因此您总是可以尽可能地将它们打包。
发布于 2022-08-07 10:18:08
结构体的编译时标注排除了单个malloc()返回的单个内存块中各种数据类型的运行时量的混合。但是,正在运行的可执行文件可能能够计算所需的存储空间,然后分配和填充足以满足需求的块。
声明类似于以下形式的联合,这是一种数据类型,可用于为内存中正确对齐的子区域分配值。
typedef union {
char c[8];
short s[4];
int i[2];
float f[2];
double d;
} t_t;该联合的单个实例将是8个连续字节,可用于存储1xdouble、2xfloats、2xint.或8个字节。(可能应用程序需要“无符号”类型。)
下面的代码分配(一个)该联合的5个连续实例,然后使用数组和指针语法演示对块的数据写入和检索。它有点像一个“容器”,其不同的内容为代码所知。
void my_main() {
printf( "sizeof t %d\n", sizeof t_t );
t_t *x = (t_t *)malloc( 5 * sizeof t_t );
// x[0] stores an 8byte double
double *pD = &x[0].d;
*pD = 365895475.45;
// x[1] & x[2] store 4x 4byte floats
float *pF = &x[1].f[0];
pF[0] = 123.123; pF[1] = 456.456; pF[2] = 789.74; pF[3] = 42.42;
// x[3] stores a long string, spilling into x[4]
char *pC = &x[3].c[0];
strcpy( pC, "Quick brown fox" );
printf( "%l.2f %.2f %.2f %.2f %.2f %s.. and '%s'\n",
*pD, pF[0], pF[1], pF[2], pF[3], pC, &x[4].c );
}输出:
sizeof t 8
365895475.45 123.12 456.46 789.74 42.42 Quick brown fox.. and 'own fox'(注意,长字符串从x3溢出到x4。)
这只是个原型..。OP的特殊需求尚不清楚,但这说明了一种技术。
好奇的人可能会考虑使用前8个字节(或16个)来存储以下实例的类型和数量。例如,您可以存储类似于"D7I5C“的内容,以指示'packet‘中有7个双数、5个整数和一个以空结尾的字符串。维度(sizeof of & strlen())和quantities (考虑模块化)将定义所需实例的数量。
https://stackoverflow.com/questions/73266300
复制相似问题