Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Dynaamisesta muistinhallinnasta ja osoittimista

Sivun loppuun

Tumpelo [02.07.2007 10:36:45]

#

Piti tässä ruveta muokkaamaan erästä luokkaa käyttämään dynaamista muistinhallintaa... Mutta tietenkään ei tahdo oikein toimia. Minun pitäisi siis luoda float tyyppinen kaksiulotteinen taulukko. Voin tehdä sellaisen osoittimen näin:

float *heightMap = new float[WIDTH + 1, HEIGHT + 1];

Hienoa, osoitintaulukko jossa on kaksi ulottuvuutta. Noh, eikö osoitin voi osoittaa vain toiseen muuttujaan? Eli osoittimeen ei voi sijoittaa muuttujia näin:

/* Ei näin */
heightMap[x,y] = 0.0f;

Vaan pitäisi tehdä näin:

float foo = 0.0f;
heightMap[x,y] = &foo;

Eli, minun pitäisi luoda silti toinen taulukko "tavallisella menetelmällä" jotta olisi jotain minne osoittaa, mutta kun ei tavallista taulukkoa voi luoda näin:

/* Ei näin */
float heightMap[WIDTH][HEIGHT];

, kun WIDTH ja HEIGHT saadaan funktion parametrina.

Kysymys kuuluukin, että olenko nyt ymmärtänyt asiat ihan päin ****** vai pystynkö jotenkin luomaan dynaamisen korkeuskartan? Siis minun pitäisi saada float taulukko, jossa on kaksi ulottuvuutta, ja ulottuvuuksien koko saadaan funktion parametrina.

kooderi [02.07.2007 11:16:59]

#

float *heightMap = new float[WIDTH * HEIGHT];

heightMap[x*WIDTH + y] = 0.0f;

Tumpelo [02.07.2007 14:03:18]

#

kooderi kirjoitti:

float *heightMap = new float[WIDTH * HEIGHT];

heightMap[x*WIDTH + y] = 0.0f;

No mitäs uutta tässä nyt sitten oli? Teit kaksiulotteisesta taulukosta yksiulotteisen ja vähän muuntelit systeemejä. Meinaatko että kaksiulotteinen taulukko ei toimi mutta yksiulotteinen toimisi? Vähän kannattaisi selittää jo etukäteen kun sen kuitenkin tietää että jälkeenpäin satelee kysymyksiä jos ei vaivaudu.

Eipä tuo ainakaan mitään vaikuttanut, samaa muistinhallintavirhetta pukkaa ajon aikana tuolla rivillä.

koo [02.07.2007 17:18:44]

#

Kaksiulotteiset ja dynaamiset taulukot tuntuu olevan aihe, joka ei kertakaikkiaan jätä rauhaan. Olisiko tästä koodivinkistä apua? Noilla opeilla homman pitäisi onnistua ihan näin yksinkertaisesti:

#include "dynarray.hpp"

dynarray2<float> height_map(height, width);
height_map(x, y) = 0.0f;

Tehdään siis luokka (tai käytetään toisten tekemää sellaista), joka hanskaa sekä muistinhallinnan että alkioiden osoituksen.

Tumpelo kirjoitti:

Vaan pitäisi tehdä näin:

float foo = 0.0f;
heightMap[x,y] = &foo;

Tätä en ihan täysillä ymmärtänyt. Haluatko siis kaksiulotteisen taulukon, joka sisältää osoittimia? Näinkö:

#include "dynarray.hpp"

float foo = 0.0f;
dynarray2<float*> height_ptr_map(height, width);
height_ptr_map(x, y) = &foo;

Tuo kooderin konsti on muuten ihan ok, mutta siinä vain tarvii aina muistaa kirjoittaa tuo osoitus x*WIDTH+y oikein ja sitten täytyy vielä varmistaa, että delete[] tulee varmasti tehtyä (ottaen huomioon kaikki iffit, exceptionit yms.).

koo [02.07.2007 21:33:47]

#

Kappas, copy-pastesin turhan hätiköiden, nuo mainostamani taulukko-osoitukset menevät vinkissä siis tähän malliin, ihan kuin oikeilla C++-taulukoilla:

height_map[x][y] = 0.0f;

Tumpelo [03.07.2007 14:56:05]

#

Joo kiitoksia vastauksista. Ongelma on lähinnä minun hatara tietämys dynaamisesta muistinhallinnasta, mutta luettuani tämän ja monta muuta artikkelia: http://www.gamedev.net/reference/articles/article1869.asp , alkoi palaset loksahdella paikoilleen. Täytyy sanoa että erittäin hankala aihe tuo dynaaminen muistinhallinta, mutta sekin näköjään alkaa sujua kun vaan lukee ja harjoittelee tarpeeksi. Onneksi GameDevissä on hyviä ja selkeitä artikkeleja, tuo Päivi Hietasen kirja on vähän liian teoreettinen että siitä mitään ymmärtäisi.

Metabolix [03.07.2007 16:02:43]

#

Arvaapa, mitä pilkku tekee? Tässä pari esimerkkiä pilkun käytöstä:

int a = (2, 5); // a = 5;
int b = (++a, (a - 3)); // ++a; b = a - 3;
if (a == b)
  (f = fopen("tiedosto", "w")), (fprintf(f, "moi!")), fclose(f);

Tumpelo [03.07.2007 16:43:00]

#

IhQ.

koo, tuo sun template ei näytä toimivan oikein. Koetan käyttää sitä mutta ohjelma kaatuu assertion failediin ja breakpoint tulee tämmöseen kohtaan sun koodia:

template<typename T> typename dynarray2<T>::slice1
dynarray2<T>::operator[](std::size_t i)
{
        assert(i < dim0); // Tähän tuli breakpoint
        return slice1(&arr[i*dim1], dim1);
}

Koitan tutkia mikä kohta mun koodissa laukaisee tuon virheen sun koodissa... :D

Metabolix [03.07.2007 16:58:13]

#

Eikö tuo ole aivan selvä tapaus? Yrität viitata taulukon reunan yli. Eiköhän koo osaa hommansa, ja kyllä koodivinkkejä sen verran syynätään, että toimivat edes.

Tumpelo [03.07.2007 17:12:32]

#

Nojoo niin taitaa olla. Yhdessä kohtaa viittasin taulukon kohtaan [-1][-1] vaikka sellaista ei ole. Nyyh.

Mazzimo [03.07.2007 21:59:10]

#

Koska operaattori ottaa parametrikseen etumerkittömän kokonaisluvun, ja yrität syöttää sille etumerkillistä kokonaislukua, jonka arvo on < 0, muutetaan se operaattoriin mentäessä. Koska etumerkillisessä luvussa on etumerkki varattu luvun ensimmäiseen bittiin (ainakin minun tietääkseni, gurut paikatkaa), tulee muutetusta etumerkittömästä luvustä järjettömän suuri. Tästä seuraa taulukon yliluku. :)

Tumpelo [04.07.2007 09:25:16]

#

Jahas nyt vasta tutustuin assertione... Asserteihi... Asser... No kuitenki. :D Assertions, onko se sitten assertiot, assertioihin. Niin, tutustuin assertioihin, ja nyt ymmärrän miksi:

Metabolix kirjoitti:

Eikö tuo ole aivan selvä tapaus?

Riittää kyllä uutta asiaa joka päivälle... Aivan saa jännittää että mitähän uutta sitä illalla osaa mistä ei aamulla tiennyt yhtikäs mitään.

feenix [06.07.2007 10:40:29]

#

Tumpelo kirjoitti:

Jahas nyt vasta tutustuin assertione... Asserteihi... Asser... No kuitenki. :D Assertions, onko se sitten assertiot, assertioihin. Niin, tutustuin assertioihin, ja nyt ymmärrän miksi:

Assertit, assertteihin, asserteissa kun "suomea" puhutaan.


Sivun alkuun

Vastaus

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

Tietoa sivustosta