Dynamická alokace dvourozměrného pole s rozdílnou délkou 2. rozměru – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Dynamická alokace dvourozměrného pole s rozdílnou délkou 2. rozměru – C / C++ – Fórum – Programujte.comDynamická alokace dvourozměrného pole s rozdílnou délkou 2. rozměru – C / C++ – Fórum – Programujte.com

 

Kybrex
~ Anonymní uživatel
6 příspěvků
12. 10. 2011   #1
-
0
-

Zdravím,

mám kód: 

 while((ch=fgetc(file))!=EOF) {
      if(ch=='\n') {
        strSetData[line][i++]='2'; //end of the line
        if((++line)==*size){
          reallocStrSet(strSetData,size,(2*(*size)));//realokuje na větší pole (funguje)
          if(strSetData==0) {
            cout << " failed (realloc error)!" << endl;
            return false;
          }
        }
        //sizeItem=10;// zkusil jsem zakomentovat
        i=0;
        strSetData[line]=new char[sizeItem]; // zde je podezřelý řádek
      }
      
//...
    }

Plním datové pole ze souboru. Jde o binární řetězce, které jsou různě dlouhé. Alokoval jsem paměť pro 50 ukazatelů na řetězce a pak dynamicky podle potřeby inkrementuji proměnnou line, kteoru se pohybuji v poli ukazatelů a pro každý řádek v souboru opět alokuju (2. rozměr) pole pro sadu charů, ale nechápu proč když při načítání prvního řádku, který přesáhne počáteční délku pole charů (a dojde v pořádku k realokaci), tak při vytvoření nového řádku se obvykle smažou (v debuggeru je to vidět) poslední znaky z toho předchozího pole. Znamená to, že není možné mít 2 rozměrné pole s odlišnou délkou 2 rozměru v každém řádku?

Nahlásit jako SPAM
IP: 147.32.124.–
Kybrex
~ Anonymní uživatel
6 příspěvků
12. 10. 2011   #2
-
0
-

#1 Kybrex
Když se dívám na ten příspěvek, asi z něj není moc jasný můj problém (přecijen už je pozdě   )

Ve statických polích vím, že musí být druhý rozměr stejný, ani to jinak nejde - a pole se ukládá serializovaně za sebou, ale očekával jsem, že v případě dynamické alokace nebude s tímto problém:

char** pole=new char*[10];

pole[0]=new char[5];
//plním v cyklu, přijdu na to, že se data nevejdou
//>>realokuju pole[0] s překopírováním dat ;)
pole[0]=new char[10]; - mám větší pole a už se vejdu

//pak přejdu na další "řádek"
pole[1]=new char[5]; a v tuto chvíli v debuggeru vidím, jak se mi poslední znaky z pole[0] přepíší na nějaký nesmysl (napr.: z 1001010012 se stane něco jako 1001010\\023 ) - nechápu
Nahlásit jako SPAM
IP: 147.32.124.–
zlz
~ Anonymní uživatel
634 příspěvků
12. 10. 2011   #3
-
0
-

Někde máš chybu, ukaž víc kódu.

Nahlásit jako SPAM
IP: 213.211.51.–
KIIV
~ Moderátor
+43
God of flame
12. 10. 2011   #4
-
0
-

Proc vlastne nepouzijes treba tridu string? A treba vektor na druhy rozmer?  Nebo mas nejake restriktivni zadani?

A kdyz uz sem u toho proc ne rovnou i ifstream na nacitani dat ze souboru :)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
kybrex0
Duch
12. 10. 2011   #5
-
0
-

#4 KIIV
Je to semestrální práce do školy a budeme to pak přepisovat pro paralelní spracování a doporučovali nám, že se máme vyhnout strukturám jako je string a podobným vymoženostem. :) 

Posílám víc kódu

#include <iostream>
#include <stdio.h>

using namespace std;

int searchInStr(char*, char*);
bool testString(char*, char**, int, int*);
void printResult(char*, char**, int, int*);
bool loadStrSet(char**&,int*);
void reallocStrSet(char** , int *, int);
void reallocStr(char* &, int *, int);

int main()
{
  //testování
  char** superStrings=new char*[1]; // zkoumané nadřetězce
  superStrings[0]=new char[30];

  superStrings[0][0]='1';
  superStrings[0][1]='0';
  superStrings[0][2]='1';
  superStrings[0][3]='0';
  superStrings[0][4]='0';
  
  superStrings[0][5]='1';
  superStrings[0][6]='0';
  superStrings[0][7]='0';
  superStrings[0][8]='1';
  superStrings[0][9]='0';
  
  superStrings[0][10]='1';
  superStrings[0][11]='0';
  superStrings[0][12]='1';
  superStrings[0][13]='0';
  superStrings[0][14]='0';
  
  superStrings[0][15]='0';
  superStrings[0][16]='1';
  superStrings[0][17]='0';
  superStrings[0][18]='0';
  superStrings[0][19]='1';
  
  superStrings[0][20]='0';
  superStrings[0][21]='0';
  superStrings[0][22]='1';
  superStrings[0][23]='1';
  superStrings[0][24]='2';
  
  char** strSetData=NULL;
  int size=0;
  if(!loadStrSet(strSetData,&size)) {
      cout << "Loading file failed!" << endl;
      return 0;
  }
  int* searched=new int[size];
  
  for(int i=0;i<1;i++) {
    if(testString(superStrings[i], strSetData, size, searched)) {
      cout << "nalezeno" << endl;
      printResult(superStrings[i], strSetData, size, searched);
    }
    else cout << "nenalezeno" << endl;
  }
  
  delete[] superStrings[0];
  delete[] superStrings;
  
  for(int i=0;i<size;i++) {
//      cout << strSetData[i] << endl;
    delete[] strSetData[i];
  }
  delete[] strSetData;  
  
  return 0;
}
//...
bool loadStrSet(char** &strSetData, int* size) {
  cout << "Loading file ...";
  *size=50;
  int sizeItem=10;  
  FILE * file=0;
  char ch;
  int line=0;
  int i=0;
  file=fopen("strset.txt","r");
  if(file!=NULL) {
    strSetData=new char*[*size];
    strSetData[line]=new char[sizeItem];
    while((ch=fgetc(file))!=EOF) {
      if(ch=='\n') {
        strSetData[line][i++]='2'; //end of the line - není třeba realokovat pole, je to poslední znak
        if((++line)==*size){
          reallocStrSet(strSetData,size,(2*(*size)));
          if(strSetData==0) {
            cout << " failed (realloc error)!" << endl;
            return false;
          }
        }
        //sizeItem=10;
        i=0;
        strSetData[line]=new char[sizeItem]; // zde se to pokazí, když se řádek předtím realokovalo
      }
      
      if(ch=='0' || ch=='1') {
        strSetData[line][i++]=ch;
        if(i==sizeItem) {
          reallocStr(strSetData[line],&sizeItem,2*sizeItem);
          if(strSetData[line]!=0) {
            sizeItem=2*sizeItem;
          } else {
            cout << " failed (realloc error)!" << endl;
            return false;
          }
        }
      }
    }
    strSetData[line][i]='2';
    *size=line+1;
    cout << "done" << endl;
    return true;
  } else {
    cout << " failed!" << endl;
    return false;
  }
}

void reallocStrSet(char** p, int* actSize, int newSize) {
  char** tmp=new char*[newSize];
  for(int i=0;i<*actSize;i++)
    tmp[i]=p[i];
  delete[] p;
  p=tmp;
  *actSize=newSize;
}

void reallocStr(char* &p, int* actSize, int newSize) {
  char* tmp=new char[newSize];
  for(int i=0;i<*actSize;i++)
    tmp[i]=p[i];
  delete[] p;
  p=tmp;
  *actSize=newSize;
}
Nahlásit jako SPAM
IP: 83.208.9.–
KIIV
~ Moderátor
+43
God of flame
12. 10. 2011   #6
-
0
-

a kde vlastne udrzujes velikost tech radku? jak to vypisujes? jestli jako retezce - mas na jejich konci ukoncovaci znak '\0' ?

Muzes pouzit na tydle saskarny spojove seznamy? Minimalne na radky je to mnohem vyhodnejsi... pak muzes nakonec akorat spocitat kolik toho mas, prekopirovat pointery do pole a zrusit spojak.

Mimo jine, zkousel si uz valgrind?

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

jo a pripada mi, ze mas chybu i tady:

void reallocStrSet(char** p, int* actSize, int newSize) 

takze vesmes udelas kopii dat z volajiciho pointeru, uvolnis z pameti, zmenis pointer ale ten uz se nedostane ven z funkce

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
kybrex0
Duch
12. 10. 2011   #8
-
0
-

#7 KIIV
Jo to je chyba, měl jsem ji ještě v té druhé funkci, ale včera v noci už jsem si nevšim, že to tam mám 2x :) díky za tip. Délku řádku neuchovávam. Mám na konci ukončovací znak (akorát jsem tam tak trochu naprasil '2' - mám v tom řetězci jen 0 a 1) Díky moc za rady. Vyzkouším to. (Programuju pod windows O:-) takže valgrind nemám, ale asi si rozjedu na virtualu linux).

Nahlásit jako SPAM
IP: 83.208.9.–
KIIV
~ Moderátor
+43
God of flame
12. 10. 2011   #9
-
0
-

velice doporucuju... na tu zapomenutou referenci bys prisel pri prvni realokaci a zapisu mimo alokovany prostor

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
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, 10 hostů

Podobná vlákna

Dynamická alokace — založil Bananovnik

Dynamická alokace paměti — založil birkof

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ý