Hei onko mahdollista luoda väliaikaisesti vaihtuvakokoinen taulu stackiin? Kokeilen ladata Vulkan kirjaston avulla tuettuja layer ominaisuuksia ja tuettuja laajennuksia, mutta en tiedä ennakolta montako niitä on kenenkin koneella, joten taulun koko pitäisi muuttaa jokaisen käyttäjän mukaan.
Nykyinen koodini on rajattu maksimissaan 16 ominaisuuteen:
uint32_t extensionCount = 16; struct VkExtensionProperties extensionProperties[16]; vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensionProperties);
Haluaisin tehdä sen seuraavasti, mutta taulun koko ei ole vakio ja se aiheuttaa käännösvirheen.
uint32_t layerCount; vkEnumerateInstanceLayerProperties(&layerCount, NULL); // lue määrä VkLayerProperties availableLayers[layerCount]; // virhe, ei vakio vkEnumerateInstanceLayerProperties(&layerCount, availableLayers); // lue layer ominaisuudet
Koodit ovat kahdesta eri kohdasta koodiani. Onko muisti pakko varata Heappiin? Käytän taulukoita vain parin rivin ajan ja heitän sitten menemään.
C-koodina tuo kyllä toimii. Valitse vain jokin alle 20 vuotta vanha C-standardi, esimerkiksi C99 tai C11.
C++ ei tue tätä, vaan siinä muisti täytyy varata erikseen.
Tuossa yllä tuli tosiaan kattavasti kuvaus siitä, miten kielten varsinaiset taulukot toimivat. Useimmilla käytetyimmistä alustoista on kuitenkin saatavilla alustakohtainen keino saavuttaa oleellisesti se, mitä haluat tehdä eli tilaa pinosta ajonaikana määräytyvä määrä – alloca
-funktiolla (tai vastaavalla; ota selvää oman alustasi yksityiskohdista).
alloca
n käyttö vastaa puoliksi perinteistä dynaamista muistinvarausta C:ssä, sillä merkittävällä erolla että tällä tavalla varattua muistia ei voi, eikä pidä yrittää vapauttaa itse. Esimerkiksi C++:aa käytettäessä jälki ei siis ole kovin nättiä, mutta voisit kuitenkin kirjoittaa jotain seuraavan kaltaista:
#include <alloca.h> // tarkista tarvittava tiedosto järjestelmäsi dokumentaatiosta int count = get_count(); VkLayerProperties* layers = static_cast<VkLayerProperties*>(alloca(count * sizeof(*layers));
alloca
saattaa tietyntyyppisessä käytössä saada hieman nopeusetua verrattuna muuhun dynaamiseen muistinvaraukseen, mutta pinon käytöstä puhuessa lienee itse kunkin hyvä muistaa, että pinon suurin mahdollinen koko on tyypillisesti vain murto-osa käytettävissä olevasta muistista, ja rajan ylittämisestä paraskin mahdollinen seuraus on se, että ohjelma kaatuu välittömästi ja näyttävästi. Huomionarvoista on myös se, että alloca
eroaa varsinaisista taulukoista siinä, että sen varaaman tilan elinikä ei rajaudu lohkoihin, vaan funktioihin. Erityisesti käytettäessä alloca
a silmukoiden sisällä tulee varmistaa, että todella tietää mitä on tekemässä.
eq kirjoitti:
Esimerkiksi C++:aa käytettäessä jälki ei siis ole kovin nättiä, mutta voisit kuitenkin kirjoittaa jotain seuraavan kaltaista:
#include <alloca.h> // tarkista tarvittava tiedosto järjestelmäsi dokumentaatiosta int count = get_count(); VkLayerProperties* layers = static_cast<VkLayerProperties*>(alloca(count * sizeof(*layers));
Vielä kauheamman näköistä olisi, jos pitäisi varata tila moniulotteiselle taulukolle ja käsitellä sitä.
C:n tapa käyttää osoittimia on ruma ja voi pahimmillaan saada aikaan erittäin vaikeaselkoista koodia.
PL/I:n tapa on mielestäni paljon parempi ja saa aikaan paljon helppolukuisempaa koodia:
dcl p ptr; dcl array(200, 200) fixed bin(31) based(p); alloc array; /* tee jotain... */ array(1, 1) = 10; free array;
dynaamisesti muistin varaaminen pinoon onnistuisi PL/I:llä yksinkertaisesti laittamalla muuttuja begin lohkon sisään.
Mites tämä PL/I taas liittyikään kysymykseen?
groovyb kirjoitti:
Mites tämä PL/I taas liittyikään kysymykseen?
Kunhan mainitsin C:n osoitin ja taulukko toteutuksen huonoudesta. Tiedätkö muuten mistä ohjelmointikielestä C osoittimensa "lainasi"?
Harmi vaan, että samoin kuin kävi esikääntäjän kanssakin, niin C sai osoittimista ja taulukon käsittelystäkin rampautetut toteutukset.
jalski kirjoitti:
Tiedätkö muuten mistä ohjelmointikielestä C osoittimensa "lainasi"?
Assemblerista? :o
Tosiaan PL/I ei liity mitenkään tähänkään kysymykseen, mutta jalski nyt on tälläinen ärsyttävä PL/I fanaatikko joka käy kehumassa sitä joka ketjussa jossa vaan voi... Vähän niinkuin monilla foorumeilla oli joskus Linux-fanaatikkoja jotka kävi kehumassa sen ylivertaisuutta joka toisessa Windows-ketjussa tai vaikka Apple-fanaatikkoja jotka aina tuo sen ylivertaisuuden tai kasvissyöjiä.
Toki kaikilla edellä mainituilla on myös järkeviä faneja, jotka ei tuo oman suosikin parhautta esille joka käänteessä.
Metabolix kirjoitti:
C-koodina tuo kyllä toimii. Valitse vain jokin alle 20 vuotta vanha C-standardi, esimerkiksi C99 tai C11.
Käytän koodausympäristönä Visual Studiota 2017, joten oletuksena kääntäjänä toimii msvc, joka pikaisen selvityksen perusteella tukee vain C90 standardia. Täytyy siis vaihtaa kääntäjä tai käyttää Heappiin varattua muistia.
Muille tiedoksi, että haluamani ominaisuuden nimi on uudemmissa C-standardeissa variable length arrays (VLA).
jalski kirjoitti:
PL/I:n tapa on mielestäni - -
Alkuperäinen viestini taisi olla epäselvä, kun vain otsikossa otin kielen puheeksi. Tarkoitus on löytää (standardi)ratkaisu C-kielelle, ei C++ tai millekään toiselle kielelle.
eq kirjoitti:
Tuossa yllä tuli tosiaan kattavasti kuvaus siitä, miten kielten varsinaiset taulukot toimivat. Useimmilla käytetyimmistä alustoista on kuitenkin saatavilla alustakohtainen keino saavuttaa oleellisesti se, mitä haluat tehdä eli tilaa pinosta ajonaikana määräytyvä määrä –
alloca
-funktiolla (tai vastaavalla; ota selvää oman alustasi yksityiskohdista).
Alloca näyttäisi löytyvän monelle alustalle. Kiitos vinkistä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.