Wpis z mikrobloga

#programowanie #include dam #cpp bo #c nie moge

Mam taki kod:


#include 
#include 
#include 
#include 
``````
char * getRandomString(int aCount);
``````
int main()
{
    
char * ptr;
    
while(1)
    {
        ptr = getRandomString(255);
        free(ptr);
        printf(
"%s\n", ptr);
        sleep(1);
    }
``````
    
return 0;
}
``````
char * getRandomString(int aCount)
{
    
int iCharType;
    
char cChar;
    
char * pcDest;
``````
    
if(aCount <= 0)
        
return pcDest = NULL;
``````
    pcDest = (
char*)malloc(sizeof(char)*(aCount+1));
``````
    /* initialize random seed: */
    srand (time(
NULL));
``````
    
while(aCount--)
    {
        iCharType = rand() % 3; // Rand type of char (Num, Upper case, Lower case)
``````
        
switch(iCharType)
        {
            
case 0 : cChar = rand() % 10;
            cChar += 48; // We need number
            
break;
            
case 1 : cChar = rand() % 26;
            cChar += 65; // We need capital letter
            
break;
            
case 2 : cChar = rand() % 26;
            cChar += 97; // We need small letter
            
break;
        }
        strncat(pcDest, &cChar, 1);
    }
``````
    
return pcDest;
}

Jest funkcja getRandomString() która alokuje pamięć i zwraca do niej adres.
W main jest pętla która do wskaźnika ptr przypisuje adres jaki dosteje od f. getRandomString(), później zwalnia pamieć pod ptr, czeka sekunde, ponownie przypisuje, zwalnia i... wyrzuca mnie z programu z błędem typu:

free(): invalid next size (normal)

albo

double free or corruption (!prev)


Dlaczego tak się dzieje?
  • 17
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@olewales: Bo jest 5:30 ( ͡° ͜ʖ ͡°)
To jest pozostałość po tym jak przy pomocy printów próbowałem debuguwać program.
ten printf() jest nieszkodliwy, można go spokojnie wyrzucić, program dalej się wysypie.
  • Odpowiedz
@K5HV: GDB is your friend! A jak masz Windowsa to użyj Visual Studio. Super się w nim debuguje.

Edit:
W którym miejscu funkcji dopisujesz na końcu ciągu znakowego '\0' ?
  • Odpowiedz
@K5HV: pisanie kodu który jest bardziej explicit (jak to się tłumaczy?) jest potem łatwiejsze w debugowaniu właśnie niż skakanie po dokumentacjach.
  • Odpowiedz
via Android
  • 0
@RARvolt: chyba nie dokońca rozumiem o co ci chodzi. ;)

Funkcja getRandomString(), robi raczej to czego od niej wymagam. Nie rozumiem tylko dlaczego, gdy do ptr przypisze wynik tej funkcji, to ptr powinien wskazywać na adres zaalokowany przez malloc() wewnątrz tej funkcji.
W takim razie wykonanie free() na ptr jest wskazane kiedy nie potrzebuje już korzystać z tego stringa, problem polega na tym, że gdy jeszcze raz do ptr przypisze wynik mojej
  • Odpowiedz
@K5HV: @RARvolt ma na myśli, że każdy string w C++ kończy się znakiem null byte-a czyli '\0', a Ty w swoim kodzie nigdzie go nie podajesz, więc teoretycznie string jest nie skończony?
  • Odpowiedz
via Android
  • 0
@Analityk: tak, nie.
strncpy() przyjmuje trzy argumenty. CEL, ZRODLO oraz DLUGOSC.
ZRODLO oraz CEL to cstringi - char*.
DLUGOSC określa ile znaków ze ZRODLA mają być przekopiowane do celu.
W CELU funkcja ta szuka znaku \0, usuwa go, dodaje tyle znaków ze ZRODLA ile wynosi długość i dodaje na końcu \0.
Nie używa realloc(), CEL musi być odpowiednio duży by
  • Odpowiedz
@K5HV: To sprawdź co masz w celu przed wywołaniem strncat.
Nadpisujesz pamięć bo za drugim razem malloc zwraca ci do pcDest ten sam adres i tam pierwszy null jest już na pozycji ostatniej możliwej. Przypisanie cchar następuje poza zasięgiem ptr.
Najlepiej po malloc wyzeruj pamięć.
  • Odpowiedz
via Android
  • 0
@Analityk: jak z tego kodu który wrzuciłem usunę free() oraz dodam printf żeby wyświetlić ptr to co sekundę dostane losowy string.
Czyli tutaj wszystko działa.

Jak sprawdzałem przy pomocy printf("%p", ptr) to za każdym razem ptr wskazywał na inny adres.
Tutaj też wszystko
  • Odpowiedz