首页 > 编程语言 >C/C++中的变长结构体

C/C++中的变长结构体

时间:2023-06-14 18:38:04浏览次数:36  
标签:node kdtree int C++ mt 变长 sizeof include 结构


1. 问题来源

首先看下如下的一段代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAX_LEN 1024

typedef struct KDtree{
    double data[MAX_LEN]; // 数据
    int dim; // 选择的维度
    struct KDtree *left; // 左子树
    struct KDtree *right; // 右子树
}kdtree_node;

int main()
{
    kdtree_node *kd_node = (kdtree_node *)malloc(sizeof(kdtree_node));
    printf("kdtree_node: %ld\n", sizeof(kdtree_node)); // 8216
    printf("kd_node: %ld\n", sizeof(kd_node));
    free(kd_node);

    return 0;
}

在这段代码中,为了存储数据,申请了最大长度为1024的double型数组。若是数据的长度远远小于MAX_LEN,这样的写法,是及其浪费空间的。

2. 解决的方法

在C语言中,有如下的一种构建方法:

struct mumble {
	//stuff
	char pc[];    
};

对于这种最后一个成员的长度不固定的写法称为柔性数组,也叫伸缩性数组,即变长数组。即声明结构体的时候不指定声明的数组的大小,等到需要使用的时候根据具体情况申请足够大小的空间。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct mytest{
	int a;
	double b;
	int c[];  //c不占用空间,只是作为一个符号地址存在,而且必须是结构体的最后一个成员
}mt;

int main(){
    printf("mt: %ld\n", sizeof(mt));  // 16
	int t[10] = {0,1,2,3,4,5,6,7,8,9};
	mt* pmt = (mt*)malloc(sizeof(mt) + sizeof(int)*10 + 1);
    int i = 0;
    if (NULL != pmt){
        pmt->a = 1;
        pmt->b = 11;
        for (i = 0; i < 10; i++) {
            (pmt->c)[i] = t[i];
        }
    }
    free(pmt);
    return 0;
}

至于这里的sizeof(mt)为什么是16,涉及到sizeof对结构体计算时的地址对齐问题。意:柔性数组只能为结构体的最后一个成员。

参考文献

  • 柔性数组-读《深度探索C++对象模型》有感


标签:node,kdtree,int,C++,mt,变长,sizeof,include,结构
From: https://blog.51cto.com/u_16161414/6479826

相关文章

  • C/C++——排序
    在C/C++中的排序,使用到的函数主要有:sort()qsort()下面详细分析sort()函数和qsort()函数。1、sort()函数sort()是STL中提供的算法,头文件为:#include<algorithm>usingnamespacestd;函数原型如下:template<classRandomAccessIterator>voidsort(RandomAccessIteratorfirst,Ran......
  • 挑战数据结构和算法面试题——最大差值
    题目来自伯乐在线,欢迎有不同答案的同学来一起讨论。分析:基本方法是遍历数组,找到当前值前面所有数组元素的最小值。方法:intget_max_distance(int*a,constintn){intmax_distance=0;//纪录最大距离if(n==0)returnmax_distance;intmin=a[0];//纪录最小的......
  • C/C++——map的基本操作总结
    标准库map类型是一种以键-值(key-value)存储的数据类型。以下分别从以下的几个方面总结:map对象的定义和初始化map对象的基本操作,主要包括添加元素,遍历等1、pair类型1.1、pair类型的定义和初始化pair类型是在有文件utility中定义的,pair类型包含了两个数据值,通常有以下的一些定义和初......
  • C/C++——vector的基本操作总结
    标准库vector类型是C++中使用较多的一种类模板,vector类型相当于一种动态的容器,在vector中主要有一些基本的操作,接下来分别从以下的几个方面总结:vector对象的定义和初始化vector对象的基本操作,主要包括添加元素,遍历等1、vector对象的定义和初始化在vector中主要有四种定义和初始化的......
  • 【数据结构与算法面试题】求和
    题目来源“数据结构与算法面试题80道”。问题分析:可以使用类的构造方法,在类的每次实例化对象时都会调用构造方法,那么只需要实例化n个对象,就会调用n次构造方法,这就模拟了循环的过程,此时,只需要有一个全局变量记录累加的值即可。方法:#include<stdio.h>classcalnum{ public: cal......
  • tomcat的文件结构和组成
    目录结构 TRANSLATEwithxEnglishArabicHebrewPolishBulgarianHindiPortugueseCatalanHmongDawRomanianChineseSimplifiedHungarianRussianChineseTraditionalIndonesianSlovakCzechItalianSlovenianDanishJapaneseSpanis......
  • 将easyui-datagrid组件克隆至另一个 easyui-datagrid组件 表结构(列)及数据完全一样
    将grid组件克隆至grid_toexcel组件表结构(列)及数据完全一样html<tableid='grid'class='easyui-datagrid'style='width:1250px;min-height:450px'title='列表'iconCls='icon-table'pagination='true'......
  • C++ OpenMP、TBB库的简单使用
    1.OpenMP的简单使用OpenMP可以用来并行计算for循环,提高程序运行速度。首先要打开OpenMP支持:“配置属性”——“C/C++”——“语言”——“1.OpenMP支持”后选择“是”。1omp_get_num_procs()//获取系统中处理器的个数2omp_set_num_threads(num_count)/......
  • C++ 中的运算符重载
     您可以重定义或重载大部分C++内置的运算符。这样,您就能使用自定义类型的运算符。重载的运算符是带有特殊名称的函数,函数名是由关键字operator和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。https://www.tzffs.com/lnzt15/......
  • C++ 多态
     多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。下面的实例中,基类Shape被派生为两个类https://www.tzffs.com/mnst14/......