void virDomainDefFree(virDomainDefPtr def)
{
    size_t i;

    if (!def)
        return;

    virDomainResourceDefFree(def->resource);

    for (i = 0; i < def->maxvcpus; i++)
        virDomainVcpuDefFree(def->vcpus[i]);
    VIR_FREE(def->vcpus);

    /* hostdevs must be freed before nets (or any future "intelligent
     * hostdevs") because the pointer to the hostdev is really
     * pointing into the middle of the higher level device's object,
     * so the original object must still be available during the call
     * to virDomainHostdevDefFree().
     */
    for (i = 0; i < def->nhostdevs; i++)
        virDomainHostdevDefFree(def->hostdevs[i]);
    VIR_FREE(def->hostdevs);

    for (i = 0; i < def->nleases; i++)
        virDomainLeaseDefFree(def->leases[i]);
    VIR_FREE(def->leases);

    for (i = 0; i < def->ngraphics; i++)
        virDomainGraphicsDefFree(def->graphics[i]);
    VIR_FREE(def->graphics);

    for (i = 0; i < def->ninputs; i++)
        virDomainInputDefFree(def->inputs[i]);
    VIR_FREE(def->inputs);

    for (i = 0; i < def->ndisks; i++)
        virDomainDiskDefFree(def->disks[i]);
    VIR_FREE(def->disks);

    for (i = 0; i < def->ncontrollers; i++)
        virDomainControllerDefFree(def->controllers[i]);
    VIR_FREE(def->controllers);

    for (i = 0; i < def->nfss; i++)
        virDomainFSDefFree(def->fss[i]);
    VIR_FREE(def->fss);

    for (i = 0; i < def->nnets; i++)
        virDomainNetDefFree(def->nets[i]);
    VIR_FREE(def->nets);

    for (i = 0; i < def->nsmartcards; i++)
        virDomainSmartcardDefFree(def->smartcards[i]);
    VIR_FREE(def->smartcards);

    for (i = 0; i < def->nserials; i++)
        virDomainChrDefFree(def->serials[i]);
    VIR_FREE(def->serials);

    for (i = 0; i < def->nparallels; i++)
        virDomainChrDefFree(def->parallels[i]);
    VIR_FREE(def->parallels);

    for (i = 0; i < def->nchannels; i++)
        virDomainChrDefFree(def->channels[i]);
    VIR_FREE(def->channels);

    for (i = 0; i < def->nconsoles; i++)
        virDomainChrDefFree(def->consoles[i]);
    VIR_FREE(def->consoles);

    for (i = 0; i < def->nsounds; i++)
        virDomainSoundDefFree(def->sounds[i]);
    VIR_FREE(def->sounds);

    for (i = 0; i < def->nvideos; i++)
        virDomainVideoDefFree(def->videos[i]);
    VIR_FREE(def->videos);

    for (i = 0; i < def->nhubs; i++)
        virDomainHubDefFree(def->hubs[i]);
    VIR_FREE(def->hubs);

    for (i = 0; i < def->nredirdevs; i++)
        virDomainRedirdevDefFree(def->redirdevs[i]);
    VIR_FREE(def->redirdevs);

    for (i = 0; i < def->nrngs; i++)
        virDomainRNGDefFree(def->rngs[i]);
    VIR_FREE(def->rngs);

    for (i = 0; i < def->nmems; i++)
        virDomainMemoryDefFree(def->mems[i]);
    VIR_FREE(def->mems);

    virDomainTPMDefFree(def->tpm);

    for (i = 0; i < def->npanics; i++)
        virDomainPanicDefFree(def->panics[i]);
    VIR_FREE(def->panics);

    VIR_FREE(def->iommu);

    VIR_FREE(def->idmap.uidmap);
    VIR_FREE(def->idmap.gidmap);

    VIR_FREE(def->os.machine);
    VIR_FREE(def->os.init);
    for (i = 0; def->os.initargv && def->os.initargv[i]; i++)
        VIR_FREE(def->os.initargv[i]);
    VIR_FREE(def->os.initargv);
    for (i = 0; def->os.initenv && def->os.initenv[i]; i++) {
        VIR_FREE(def->os.initenv[i]->name);
        VIR_FREE(def->os.initenv[i]->value);
        VIR_FREE(def->os.initenv[i]);
    }
    VIR_FREE(def->os.initdir);
    VIR_FREE(def->os.inituser);
    VIR_FREE(def->os.initgroup);
    VIR_FREE(def->os.initenv);
    VIR_FREE(def->os.kernel);
    VIR_FREE(def->os.initrd);
    VIR_FREE(def->os.cmdline);
    VIR_FREE(def->os.dtb);
    VIR_FREE(def->os.root);
    VIR_FREE(def->os.slic_table);
    virDomainLoaderDefFree(def->os.loader);
    VIR_FREE(def->os.bootloader);
    VIR_FREE(def->os.bootloaderArgs);

    virDomainClockDefClear(&def->clock);

    VIR_FREE(def->name);
    virBitmapFree(def->cpumask);
    VIR_FREE(def->emulator);
    VIR_FREE(def->description);
    VIR_FREE(def->title);
    VIR_FREE(def->hyperv_vendor_id);

    virBlkioDeviceArrayClear(def->blkio.devices,
                             def->blkio.ndevices);
    VIR_FREE(def->blkio.devices);

    virDomainWatchdogDefFree(def->watchdog);

    virDomainMemballoonDefFree(def->memballoon);
    virDomainNVRAMDefFree(def->nvram);
    virDomainVsockDefFree(def->vsock);

    for (i = 0; i < def->mem.nhugepages; i++)
        virBitmapFree(def->mem.hugepages[i].nodemask);
    VIR_FREE(def->mem.hugepages);

    for (i = 0; i < def->nseclabels; i++)
        virSecurityLabelDefFree(def->seclabels[i]);
    VIR_FREE(def->seclabels);

    virCPUDefFree(def->cpu);

    virDomainIOThreadIDDefArrayFree(def->iothreadids, def->niothreadids);

    virBitmapFree(def->cputune.emulatorpin);
    VIR_FREE(def->cputune.emulatorsched);

    virDomainNumaFree(def->numa);

    virSysinfoDefFree(def->sysinfo);

    virDomainRedirFilterDefFree(def->redirfilter);

    for (i = 0; i < def->nshmems; i++)
        virDomainShmemDefFree(def->shmems[i]);
    VIR_FREE(def->shmems);

    for (i = 0; i < def->nresctrls; i++)
        virDomainResctrlDefFree(def->resctrls[i]);
    VIR_FREE(def->resctrls);

    VIR_FREE(def->keywrap);

    if (def->namespaceData && def->ns.free)
        (def->ns.free)(def->namespaceData);

    virDomainSEVDefFree(def->sev);

    xmlFreeNode(def->metadata);

    VIR_FREE(def);
}