Délka pole – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Délka pole – C / C++ – Fórum – Programujte.comDélka pole – C / C++ – Fórum – Programujte.com

 

Scorpio
~ Anonymní uživatel
7 příspěvků
19. 3. 2012   #1
-
0
-

Ahoj. Mám pole v C, které je definováno takhle 



    R = (char**)malloc(o * sizeof(char *));
    for (i = 0; i < o; i++) {
        R[i] = (char*)malloc(2 * sizeof(char));
    }

Je to dvourozměrné pole o rozměrech N x 2.
Potřebuju zjistit ve funkci, do které posílám pointer na to pole jako parametr, kolik má řádků, tedy N.
Když se to snažím počítat přes sizeof či podobně, tak mi to nikdy nevychází.

Díky za odpověď.

Nahlásit jako SPAM
IP: 89.203.212.–
KIIV
~ Moderátor
+43
God of flame
19. 3. 2012   #2
-
0
-

sizeof funguje jen pro staticky alokovany pole.. proste musis nekde udrzet velikost nebo mit prvni rozmer o jednotku vetsi a hodit tam "terminacni" hodnotu - u pointeru je to vzdy NULL

u druheho rozmeru predpokladam ze to je retezec.. tam se pouzije standardni ukonceni: znak '\0' (samo s nim musis pocitat pri alokaci)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
meqi+1
Newbie
19. 3. 2012   #3
-
0
-

Toto bohužel nejde no, jak říkal KIIV, tak si někde musíš uchovávat velikosti, protože u dvojrozměrně alokovanýho pole, se druhá část ukládá na jiný místo v paměti a tady to jde pouze odkazama, takže když se snazíš zjistit velikost, tak ti to vždy hodí velikost odkazu (čili 4)

Druhá věc je, kdyby si chtěl třeba pole slov přes chary.. to můžeš udělat takto a velikost zjistit už jde (jedná se o statický pole) 

char* pole[10];

for (int i = 0; i < 10; i++)
    *(pole + i) = "bagr";

int size = sizeof(pole) / sizeof(*pole); // 10

Dřív, když jsem řešil matice, tak jsem si vytvářel struktůru, kde byla jednak matice a taky její velikost a tuto celou struktůru jsem předával v parametrech, takže jsem se nemusel starat o její velikost... viz. příklad jak jsem to měl: 

template <typename T>
struct DoubleField
{
	T** Matrix;
	int Row;
	int Column;

	DoubleField() : Matrix(0), Row(0), Column(0) { }
	DoubleField(const int row, const int col) : Matrix(0), Row(row), Column(col) { }

	void allocate()
	{
		if (Row > 1 && Column > 1)
		{
			Matrix = new T*[Row];

			for (int i = 0; i < Row; i++)
				*(Matrix + i) = new T[Column];
		}
	}

	void allocate(const int row, const int col)
	{
		Matrix = new T*[row];
		Row = row;
		Column = col;

		for (int i = 0; i < row; i++)
			*(Matrix + i) = new T[col];
	}

	void free()
	{
		for (int i = 0; i < Row; i++)
			delete[] *(Matrix + i);

		delete[] Matrix;
	}
};

A použití potom: 

DoubleField<int> data(5, 7);
data.allocate();

int row = data.Row; // 5
int column = data.Column; // 7
int** matrix = data.Matrix; // allocate matrix

// ...

data.free();


Nahlásit jako SPAM
IP: 213.168.183.–
Scorpio
~ Anonymní uživatel
7 příspěvků
20. 3. 2012   #4
-
0
-

Díky za odpovědi. Mají to být prvky z relace.

Teď jsem ale narazil na další problém.

Takhle vypadá f-ce na přidávání prvku do pole. Hodnota [0][0] slouží jako počet řádků, takže prvky relace jsou od 1. Funguje to tak, že f-ce založí nové pole větší o jeden řádek a vrátí na ni pointer. 

char** PridatPrvek(char **R, char a, char b) {
    char **Ret;
    if (R[0][0] > 0) {
        int i;
        int m = R[0][0] + 1;
        Ret = (char**)malloc(m * sizeof(char*));
        for (i = 0; i < m; i++) {
            Ret[i] = R[i];
        }
        Ret[0][0] = m;
        Ret[m] = (char*)malloc(2 * sizeof(char));
        Ret[m][0] = a;
        Ret[m][1] = b;
    } else {
        Ret = (char**)malloc(sizeof(char*));
        Ret[0] = (char*)malloc(2 * sizeof(char));
        Ret[1] = (char*)malloc(2 * sizeof(char));
        Ret[0][0] = 1;
        Ret[1][0] = a;
        Ret[1][1] = b;
    }
    return(Ret);
}

Takže při přidávání to vypadá nějak takhle

    char **R;
    R = (char**)malloc(sizeof(char*));
    R = PridatPrvekR(R, 0, 2);

Jenže u cca 12ti prvků to hodí chybu za běhu. Když chci vytvořit to nové pole Ret 

Ret = (char**)malloc(PocetR * sizeof(char*));

Jako kdyby byla nějak omezená paměť na alokaci.

Nevíte co s tím? Díky za odpovědi.


Nahlásit jako SPAM
IP: 89.203.212.–
zlz
~ Anonymní uživatel
634 příspěvků
20. 3. 2012   #5
-
0
-

Kolik je PocetR ? Po vytvoření toho pole ho inicializuješ ? A když ho zvětšuješ a alokuješ to nové pole (btw. existuje realloc), tak to původní uvolňuješ ?

A hlavně, když má pole velikost M, tak obsahuje indexy 0..M-1.

Nahlásit jako SPAM
IP: 78.156.159.–
zlz
~ Anonymní uživatel
634 příspěvků
20. 3. 2012   #6
-
0
-

A ten speciální význam [0][0] zruš, akorát tím nasekáš další chyby. Jestli chceš mít data i rozměry pohromadě, tak použij strukturu.

Nahlásit jako SPAM
IP: 78.156.159.–
Scorpio
~ Anonymní uživatel
7 příspěvků
20. 3. 2012   #7
-
0
-

Chybka se vloudila. Ten PocetR je z kódu co jsem zkusil psát potom, že jsem neměl počet v R[0][0], ale v externí proměnné. Problém ale byl stejný, až na to, že to hodilo chybu až po 16ti prvcích. Proto si myslím, že to bude nějak omezené pamětí.

Nahlásit jako SPAM
IP: 89.203.212.–
Scorpio
~ Anonymní uživatel
7 příspěvků
20. 3. 2012   #8
-
0
-

Bych to rád měl ve strukturách, ale bohužel musím dodržet dynamické dvourozměrné pole.

Nahlásit jako SPAM
IP: 89.203.212.–
KIIV
~ Moderátor
+43
God of flame
20. 3. 2012   #9
-
0
-

se mi stejne zda ze furt alokujes nove a nove pole a ani nezkopirujes co tam uz bylo :D

realloc neznas, ale realokovat po jedne je stejne narocne.. furt se to musi presouvat dal do pameti aby na to bylo misto :D

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV
~ Moderátor
+43
God of flame
20. 3. 2012   #10
-
0
-

+ samozrejme je trosku problem kdyz mas ty typy "char**" 0-127 neni zrovna moc rozsah pro dynamicke pole

doporucuju udelat tam to co sem zminoval - posledni prvek naalokovan a za nim jeste jeden pointer NULL

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Scorpio
~ Anonymní uživatel
7 příspěvků
20. 3. 2012   #11
-
0
-

Potřebuju mít něco, co uchová max 20 prvků, takže 127 stačí. Ale když to dělám takhle, tak jich uchovám kolem 15ti a to ještě ve všech podobných polích a potřebuju 4.

Tady přikládám celý zdroják, který jsem zatím napsal. 

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

char** PridatPrvek(char **R, char a, char b) {
    char **Ret;
    if (R[0][0] > 0) {
        int i;
        int m = R[0][0] + 1;
        Ret = (char**)malloc(m * sizeof(char*));
        for (i = 0; i < m; i++) {
            Ret[i] = R[i];
        }
        Ret[0][0] = m;
        Ret[m] = (char*)malloc(2 * sizeof(char));
        Ret[m][0] = a;
        Ret[m][1] = b;
    } else {
        Ret = (char**)malloc(sizeof(char*));
        Ret[0] = (char*)malloc(2 * sizeof(char));
        Ret[1] = (char*)malloc(2 * sizeof(char));
        Ret[0][0] = 1;
        Ret[1][0] = a;
        Ret[1][1] = b;
    }
    return(Ret);
}

int ObsahujePrvek(char **R, char a, char b) {
    if (R[0][0] > 0) {
        int i;
        for (i = 1; i <= R[0][0]; i++) {
            if (R[i][0] == a && R[i][1] == b)
                return(1);
        }
    }
    return(0);
}

void VypsatRelaci(char **R) {
    if (R[0][0] > 0) {
        int i;
        printf("{");

        for (i = 1; i <= R[0][0]; i++) {
            printf("(%d, %d), ", R[i][0], R[i][1]);
        }

        printf("}");
    }
}

int main()
{
    char **R;
    char **Ref;
    char **Sym;
    char **Tra;

    R = (char**)malloc(sizeof(char*));

    R = PridatPrvek(R, 0, 2);
    R = PridatPrvek(R, 1, 2);
    R = PridatPrvek(R, 2, 0);
    R = PridatPrvek(R, 2, 2);
    R = PridatPrvek(R, 2, 4);
    R = PridatPrvek(R, 2, 2);
    R = PridatPrvek(R, 2, 4);
    R = PridatPrvek(R, 2, 2);
    R = PridatPrvek(R, 2, 4);
    R = PridatPrvek(R, 2, 2);
    R = PridatPrvek(R, 2, 4);
    R = PridatPrvek(R, 2, 4);
    //printf("%d", ObsahujePrvek(R, 1, 2));
    VypsatRelaci(R);

    return 0;
}
Nahlásit jako SPAM
IP: 89.203.212.–
KIIV
~ Moderátor
+43
God of flame
20. 3. 2012   #12
-
0
-

doporucuju spustit pod valgrindem (a kompilace s -g3) ti to ukaze zasahy mimo pamet, neuvolnenou pamet, ztracenou pamet (tj na kterou uz nejsou zadne pointery)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV
~ Moderátor
+43
God of flame
20. 3. 2012   #13
-
0
-

no jinak nejvetsi chyba je hlavne to, ze alokujes jen pole jednoho ukazatele.... ale to misto kam chces ukladat tu velikost, na to seres

pak samozrejme kasles na jakykoliv veci jako ze kdyz alokujes vetsi blok pointeru, tak nikam nekopirujes (o starej prijdes)

no proste zacni znova a poradne - todle muzes vyhodit

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Scorpio
~ Anonymní uživatel
7 příspěvků
20. 3. 2012   #14
-
0
-

Na C nejsem bohužel žádný expert, takže pochybuju, že bych to napsal lip.

Myšlenka je, že je tam pole, který má N řádků. A když ho chci přidat, tak vytvořím pole s pamětí na N + 1 pointerů na char.

Pak zkopíruju pointery včetně R[0][0] do nového pole, abych je nemusel alokovat znovu 

	for (i = 0; i < m; i++) {
            Ret[i] = R[i];
        }

Poté naalokuju ten nový řádek 

Ret[m] = (char*)malloc(2 * sizeof(char));

A do něj přidám hodnotu.

Ještě zvýším počet v R[0][0] o jeden 

Ret[0][0] = m;

A mělo by to jet. ... A do 11ti prvků to taky jede a pak to bohužel spadne.


Každopádně už jsem to napsal jinak, ať mi to aspoň funguje a né přímo podle zadání a zítra o tom hodím řeč s učitelem. Takže díky za pomoc. ;-).


Nahlásit jako SPAM
IP: 89.203.212.–
Doomista+1
Stálý člen
20. 3. 2012   #15
-
0
-

#14 Scorpio
ono by možná úplně stačilo jednoduše si na začátku alokovat pole o dvou položkách a pak si vesele zapisovat do nealokovaný části paměti

viz:

#include <iostream>

using namespace std;

int main(){
int *pole=new int[2];
for(int a=0; a<20; a++){
pole[a]=a;
cout << pole[a];
}
cin.get();
return 0;
}

Nahlásit jako SPAM
IP: 83.240.1.–
Na vše stačí iostream...
Doomista+1
Stálý člen
20. 3. 2012   #16
-
0
-

#15 Doomista
ale osobně by mě aji zajímalo proč to doprčic nespadne :D

Nahlásit jako SPAM
IP: 83.240.1.–
Na vše stačí iostream...
zlz
~ Anonymní uživatel
634 příspěvků
20. 3. 2012   #17
-
0
-

#14 Scorpio
Tak ještě jednou. Pole M prvků obsahuje prvky 0 až M-1.

Ret = (char**)malloc(sizeof(char*));		// jeden pointer
Ret[0] = (char*)malloc(2 * sizeof(char));	// prvni
Ret[1] = (char*)malloc(2 * sizeof(char));	// druhy ?!

Ret = (char**)malloc(m * sizeof(char*));
Ret[m] = (char*)malloc(2 * sizeof(char));	// zase, Ret[m] je mimo!
Nahlásit jako SPAM
IP: 213.211.51.–
zlz
~ Anonymní uživatel
634 příspěvků
20. 3. 2012   #18
-
0
-

#16 Doomista
Protože tam náhodou nejsou data, jejichž přesmahnutí by způsobilo pád.

Nahlásit jako SPAM
IP: 213.211.51.–
Scorpio
~ Anonymní uživatel
7 příspěvků
21. 3. 2012   #19
-
0
-

#18 zlz
Ou. Už to vidím. ... Si budu muset naliskat sám, páč tu nikdo není, jestli je to ta chyba. Vyzkouším ráno. x D. Díky.

Nahlásit jako SPAM
IP: 89.203.212.–
Doomista+1
Stálý člen
21. 3. 2012   #20
-
0
-

#18 zlz
Když mám int pole[2]; a uložím do pole[5] nějakou hodnotu se kterou dále pracuju není nic proti ničemu? Vyhovuje mi, že to tak funguje, ale říkám si, že to dvakrát dobře nebude

Nahlásit jako SPAM
IP: 195.113.191.–
Na vše stačí iostream...
KIIV
~ Moderátor
+43
God of flame
21. 3. 2012   #21
-
0
-

nic proti nicemu .. akorat kdyz mas:

int pred = 1000;

char pole[2];

int neco = 1000;

hadej co se stane kdyz zapises na pozici pole[5]=13?

EDIT: tak gcc preusporada poradi .. chce to mit aspon dva retezce pak se ten druhej krasne prepisuje ....

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Doomista+1
Stálý člen
21. 3. 2012   #22
-
0
-

#21 KIIV
zajímavý... pokud to je char, tak program nespadne, ale hodnotu nikam neuloží a taky nic nepřečte z té pozice. to bych bral. ale pokud místo char je typ int, tak bezproblémů ukládám i čtu

Nahlásit jako SPAM
IP: 195.113.191.–
Na vše stačí iostream...
KIIV
~ Moderátor
+43
God of flame
21. 3. 2012   #23
-
0
-

#22 Doomista
ale ulozi... vis jak vypada veskutecnosti pamet pocitace? je to bajt vedle bajtu, kazdy bajt ma svoji adresu... kdyz neco zapisujes kam nemas, prepisujes pamet, ktera muze reprezentovat cokoliv! Az kdyz zacnes zapisovat na mista ktere ti nepatri nebo jsou chranene, pak program pada... jinak muzes klidne prepisovat instrukce programu (a velka spousta bezpecnostnich der pracuje prave na principu prepisovani pameti "za" promennejma)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Doomista+1
Stálý člen
21. 3. 2012   #24
-
0
-

#23 KIIV
ou... přece to má nějakej háček... díky, tohle jsem nevěděl a zrovna tohle by mě ve snu nenapadlo.

btw jakým způsobem v obecné rovině antiviry detekují viry? mě avg našlo trojana v prográmku, kde jsem měl 4 globální struktury a v mainu tři řádky komentů a return 0; a ve chvíli, kdy jsem do mainu dal na první řádek normální kód, avg se uklidnilo

Nahlásit jako SPAM
IP: 195.113.191.–
Na vše stačí iostream...
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 76 hostů

Podobná vlákna

Délka pole, zápis čísel — založil Korn

Délka stránky — založil Pepa

Delka iframu — založil bbtrash

Délka řetězce — založil Martin

Délka stisku klávesy — založil Kenda

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý