Przy deklarowaniu tablicy z użyciem new jest ona większa niż powinna.

0

Nie wiem, czy to dobry dział, nie czuję się szczególnie zaawansowany więc chyba tak...

No więc w pewnym konsolowym programie pewna procedura ma odczytać z pewnego pliku (nazwy w kodzie poniżej pozmieniałem, bo tak) listę paru plików (znana jest już ich ilość, ale nie nazwy) i dalej robić coś z tymi plikami, ale do tego jeszcze nie doszedłem. Może najpierw dam kod, a potem wytłumaczę...

void procedura(fstream &plik, int l)
{
    plik.open("lista.txt", ios::in);
    if(plik.good())
    {
        char data[1000];

        plik.read(data, 1000);

        plik.close();

        int num = 0, lic = 0;
        char *filez[l];

        for(int i=0; i<l; i++)
        {
            while(data[num]!=10)
            {
                lic++;
                num++;
            }
            cout<<"lic dla "<<i<<".: "<<lic<<endl; //tu cos sprawdzam, zaraz wyjasnie
            filez[i] = new char[lic];
            lic = 0;
            num++;
        }

        num = 0;
        lic = 0;

        for(int i=0; i<l; i++)
        {
            while(data[num]!=10)
            {
                filez[i][lic] = data[num];
                num++;
                lic++;
            }
            num++;
            lic = 0;
        }

        for(int i=0; i<l; i++)
        {
            plik.open(filez[i], ios::in);
            if(plik.good())
            {
                cout << "dziala"<<" "<<filez[i]<<endl; //tu tez cos sprawdzam
                plik.close();
            }
            else cout << "nie dziala"<<" "<<filez[i]<<endl; //i tu
            getch();
        }
    }
    else
    {
        kolor(12);
        cout<<"Nie udalo sie wczytac listy.";
        getch();
        exit(1);
    }
}

lista.txt:

mop.txt
mop2.txt
mop3.txt

(Nie wiem, czy to tu widać, ale po mop3.txt jest jeszcze enter.)

Wiem, że pewnie niepotrzebnie wczytuję to przez read(), ale getline() z jakiegoś powodu w ogóle nie chciał mi nic wczytywać (bufor taki duży, bo plików ma być więcej).
Program najpierw zlicza z tablicy z pobranymi danymi ilość znaków w pierwszej nazwie (a więc do znaku nowej linii, czyli w ASCII nr 10, ale to pewnie wiecie), a następnie doczepia do wskaźnika z tablicy takowych tablicę charów o długości właśnie przerabianej nazwy. No i tu pojawia się problem. Zależnie od tego, jak te nazwy wyglądają (ale nie odkryłem w tym konkretniej zależności) długość tej tablicy jest inna niż faktyczna długość nazwy, a także rozmiar w zmiennej użytej do utworzenia tej tablicy.

Wynik działania tego cuda wygląda tak:

lic dla 0.: 7
lic dla 1.: 8
lic dla 2.: 8
dziala mop.txt
nie dziala mop2.txtŻ↔ÂaŰô
nie dziala mop3.txt║↔ĚgŰô

Tak więc jak widzicie chociaż zmienna użyta przy tworzeniu tablicy ma właściwy rozmiar, tablica już jest większa. Jak to w ogóle możliwe?
Dodam, że próbowałem w różny sposób zmieniać te nazwy, czasami było dobrze, a czasem nie, wydaje się to być całkiem chaotyczne i nieprzewidywalne (również długość tego dodatkowego miejsca była różna).

4
  1. Używaj std::string
  2. Wpisywanie tablicy char wpisuje wszystko aż do bajtu \0 bo taka jest konwencja tzw C-stringow. Więc u ciebie program wpisuje bajty z pamięci leżącej za twoją tablicą, aż nie trafi na 0. Jeśli musisz używać tablicy char to potrzebujesz alokować o 1 bajt więcej i dodawać na koniec bajt 0.
1
  1. Zapoznaj się z inkrementacją, bo jej nie rozumiesz: http://4programmers.net/Forum/1101404
  2. Nie używaj innego niż angielskie nazewnictwa: http://4programmers.net/Forum/1208091
  3. Nie przekazuj zmiennych tylko po to aby użyć je jako zmienne lokalne.
  4. Dla indeksacji tablic używaj size_t ewentualnie unsigned
  5. Skróciłem ten twój kod do:
bool procedura(int count)
  {
   ifstram files("lista.txt");
   size_t pos=0;
   for(string filename;(pos<count)&&(getline(files,filename));++pos)
     {
      ifstream fin(filename.c_str());
      if(!fin) return false; // lub wyjątek, bo nie wczytało się
      cout<<"dziala"<<" "<<filename<<endl; //tu tez cos sprawdzam
      //fin.close(); // to nie koniecznie, koniec pętli, samo się zamknie.
     }
   return (pos>=count); // lub wyjątek jeżeli pos<count
  }

1 użytkowników online, w tym zalogowanych: 0, gości: 1