Dlaczego ten kawałek kodu wywołuje segmentation fault?

0

Cześć,

Miałem za zadanie skopiowanie zawartości z jednej tablicy znaków do dwóch innych tak, żeby w jednej znajdowały się same wyrazy parzyste, a w drugiej same nieparzyste, po każdym zaś wyrazie miała być spacja. Z problemem już sobie poradziłem, jednakże ciągle zastanawia mnie, dlaczego ten kawałek kodu powodował segmentation fault oraz dlaczego instrukcja break nie wyskakiwała z tej pętli for, byłbym wdzięczny, gdyby ktoś mógłby mi to mógł wytłumaczyć.

#include <iostream>
void string_kopia(char zrodlo[], char parzyste[], char nieparzyste[]);
void wyswietl(char tabl[], int ile);
using namespace std;
const int rozmiar = 120;

int main(int argc, char** argv)
{
    char wypowiedz[rozmiar] = {"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu."};
    char parz[rozmiar] = {};
    char nieparz[rozmiar] = {};
   string_kopia(wypowiedz, parz, nieparz);
    wyswietl(wypowiedz, 80);
    cout << endl;
    wyswietl(parz, 80);
    cout << endl;
    wyswietl(nieparz, 80);
    cout << endl;
   return 0;
}
void string_kopia(char zrodlo[], char parzyste[], char nieparzyste[])
{
    int ktory = 0, n =0, p = 0;
   for(int i = 0; i < rozmiar && zrodlo[i] != '0'; i++)
   {
       if(ktory % 2)
       {
           do{
           if(zrodlo[i] == '0') break;
           nieparzyste[n] = zrodlo[i];
           cout << "a teraz niep: " << nieparzyste[n] << endl;
           n++;
           }while(zrodlo[i++] != ' ' );
       }
       else
       {
           do{
            if(zrodlo[i] == '0') break;
           parzyste[p] = zrodlo[i];
           cout << "a teraz parz: " << parzyste[p] << endl;
           p++;
           }while(zrodlo[i++] != ' ');
       }
       if(zrodlo[i] == '0') break;
       ktory++;
       cout << "Zmienna ktory: " <<  ktory << endl;
   }
}
void wyswietl(char tabl[], int ile)
{
    for(int i = 0; i < ile; i++)
    {
        cout << tabl[i];
    }
}

 
0

W tych warunkach powinno być raczej ... == '\0' - porównujesz ze znakiem końca stringu a nie za znakiem 0.

0

Oczywiście, zgadzam się z Tobą, ale czy to nie jest tak, że jeżeli zainicjalizuję tablicę w ten sposób:

char tablica[8] = {"abcde" }

To tablica[6] i tablica[7] będą równe zero?

0

Tu masz segfala bo inicjalizujesz tablicę charów tablicą tablic charów.

0

Ogólnie masz wielki syf w kodzie...

  1. Tak jak napisał @byku_guzio musisz zmienić na '\0' lub na 0
  2. Tu masz poprawiony kod:
#include <iostream>

using namespace std;

void string_kopia(char zrodlo[], char parzyste[], char nieparzyste[]);
const int rozmiar = 120;
 
int main()
{
    char wypowiedz[rozmiar] = {"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu."};
    char parz[rozmiar];
    char nieparz[rozmiar];
    
    string_kopia(wypowiedz, parz, nieparz);
    cout << "Wypowiedź: " << wypowiedz << "\nParzyste: " << parz << "\nNieparzyste: " << nieparz << endl;
    
    return 0;
}
void string_kopia(char zrodlo[], char parzyste[], char nieparzyste[])
{
   int ktory = 0, n = 0, p = 0;
   
   for(int i = 0;  ; i++)
   {

       if(ktory % 2)
       {
           do{
               nieparzyste[n] = zrodlo[i];
               i++;
               n++;
           }while(zrodlo[i] != ' ' && zrodlo[i] != 0);
       
           nieparzyste[n++] = ' ';
       }
       
       else
       {
           do{
               parzyste[p] = zrodlo[i];
               i++;
               p++;
           }while(zrodlo[i] != ' ' && zrodlo[i] != 0);
               
               parzyste[p++] = ' ';
       }
       
       if(zrodlo[i] == 0) 
          break;
       
          ktory++;
   }
}

Trochę jaśniej napisany ;)

  1. Inne elementy będą zerami ale nie takimi: '0'. Ponieważ to '0' oznacza znak (zrzutuj go do int to wtedy zobaczysz że to nie jest znak o kodzie 0) a nam chodzi po prostu o null.
0
  1. Inne elementy będą zerami ale nie takimi: '0'. Ponieważ to '0' oznacza znak (zrzutuj go do int to wtedy zobaczysz że to nie jest znak o kodzie 0) a nam chodzi po prostu o null.

No to ja już nie wiem, w takim wypadku ten cytat z symfonii to brednie, tak:

Symfonia 7.5: "(...)dlatego lepiej w nowych programach stosować zamiast niego z0 (zero), bo taki jest właśnie kod ASCII znaku null"
?

No i jeszcze jedna sprawa, co z taką inicjalizacją:

char zdanie[80] = { 'l', 'o', 't'} - czy to jest C-string czy nie? Bo Grębosz napisał, że tak (ponieważ reszta elementów zawierających się w tej tablicy będzie wypełniona zerami). Pogubiłem się ;|

EDIT: Dobra, już wiem - zarówno to, co Ty napisałeś, jak i to, co Grębosz napisał, to prawda. Nie widziałem tej subtelnej różnicy pomiędzy zrodlo[i] != 0 a zrodlo[i] != '0' (gdzie w pierwszym przypadku przyrównujemy do wartości zero, gdzie właśnie tak null jest kodowany, a w drugim do znaku 0).

Temat do zamknięcia :)

0

Bo '0' == 48 a '\0' == 0. O to Gręboszowi chyba chodziło.

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