Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: Dynaaminen taulun koko stackissä

Sivun loppuun

tkok [15.09.2017 20:52:56]

#

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.

Metabolix [16.09.2017 08:48:30]

#

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.

eq [18.09.2017 13:42:38]

#

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).

allocan 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ä allocaa silmukoiden sisällä tulee varmistaa, että todella tietää mitä on tekemässä.

jalski [18.09.2017 20:48:21]

#

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.

groovyb [19.09.2017 14:39:26]

#

Mites tämä PL/I taas liittyikään kysymykseen?

jalski [19.09.2017 17:59:37]

#

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.

Grez [19.09.2017 20:40:23]

#

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ä.

tkok [21.09.2017 15:46:44]

#

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ä.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta