rzutowanie string na char* oraz łączenie tablic.

0

Witam

Mam problem z małym programem który ustawiał by czas do zamknięcia systemu. Dokładnie chodzi o rzutowanie z string na char* oraz później połączenie 2 tablic char* w jedną...

#include <iostream>
#include <windows.h>
#include <stdlib.h>

using namespace std;

char* intToStr(int n);

int main()
{
    int h,m, s;
    const string komenda = "shutdown -s -t ";

    cout << "Podaj ile godzin : ";
    cin  >> h;
    cout << "\nPodaj ile minut :";
    cin  >> m;

    s = (3600*h) + (60*m);

    char *wynik, *czas;

    czas = new char[10];

    for (int i = 0; i < 10; i++)
        czas[i] = 255;

    czas = intToStr(s);

    //system(wynik);
    // w ostateczności powinno być np : system("shutdown -s -t 3000");

    return 0;
}

// metoda ze strony 4programmers
char* intToStr(int n)
{
     int i = 0;
     char *tmp = (char*)malloc(12); // stdlib
     char *ret = (char*)malloc(12);
     if(n < 0) {
          *ret = '-';
          i++;
          n = -n;
     }
     do {
          *tmp = n % 10 + 48;
          n -= n % 10;
          if(n > 9) *tmp++;
     }
     while(n /= 10);
     while(ret[i++] = *tmp--);
     return ret;
}

Ogólnie próbowałem znak po znaku w pętli for : wynik[i] = komenda[i]. Ale później zostaje jeszcze doklejenie czasu w sekundach to tego...

1

char czas[128];
sprintf(czas,"shutdown -s -t %d",(3600h) + (60m));

0

@Lukasz94
Twój kod zawiera wycieki pamięci.

A więc tak (wiem, nie zaczyna się od więc), sam jestem początkujący ale myślę że w tym wypadku mogę pomóc samemu się przy tym ucząc. Jeśli powiem coś źle, to proszę zaawansowanych forumowiczów o poprawienie mnie.

Linijka:

czas = new char[10];

Zawiera alokację 10 elementowej tablicy charów. Tej alokacji powinna gdzieś towarzyszyć dealokacja, czyli zwolnienie pamięci w postaci

delete [] czas;

Ponieważ rezerwowałeś operatorem new [], więc musisz zwalniać pamięć operatorem delete []. Ta alokacja do zmiennej "czas" jest z tego co widzę niepotrzebna, bo i tak chwilę później wpisujesz do zmiennej "czas" rezultat zwracany przez funkcję intToStr. W tej funkcji dokonujesz dwóch alokacji:

char *tmp = (char*)malloc(12);
char *ret = (char*)malloc(12);

przy pomocy malloca (nawiasem mówiąc po co używać tu malloca, skoro w c++ mamy new ?). Rezultat zwracany do ret jest zwracany z funkcji intToStr i to funkcja wywołujące tę funkcję (w tym wypadku main) odpowiada za zwolnienie pamięci (przy pomocy free()) kryjącej się pod wskaźnikiem ret. Pamięci wskazywanej przez tmp nigdzie nie zwalniasz - a powinieneś to zrobić w intToStr, bo tylko ta funkcja używa tmp. W intToStr manipulujesz tmp więc nie możesz też zrobić po prostu free(tmp);

Zauważ, że łańcuchy wpisujesz do pamięci zarezerwowanej mallociem. Funkcja malloc nie zeruje rezerwowanej pamięci, dlatego powinieneś zadbać w tym kodzie o zakończenie każdego łańcucha nullem. Łatwiej chyba rezerwować pamięć funkcją calloc() (http://www.cplusplus.com/reference/cstdlib/calloc/), która zeruje pamięć.

Linijka

while(ret[i++] = *tmp--);

Ten warunek chyba nie jest za dobry, bo nie da się przewidzieć kiedy będzie fałszywy. Przy dekrementowaniu tmp trzeba uważać, żeby nie wyjechać przed tablicę, bo to oznacza zachowanie niezdefiniowane.

Linijka

if(n > 9) *tmp++;

Odczytywanie wartości z tmp (poprzez operator *) jest tu niepotrzebne, bo nic z tym nie robisz.
Jak kompilujesz programy, to używaj opcji -Wall. Pozwala to wykryć niektóre błędy. Jeśli używasz środowiska, to opcję tę ustawiasz gdzieś w opcjach projektu, jak kompilujesz w wierszu polecenia, to g++ -Wall <plik.cpp> -o <nazwa_programu>. Jeśli używasz linuxa, to polecam program valgrind, który pozwala na wykrywanie wycieków (takich jak w Twoim programie) i innych błędów pamięci. Używa się bardzo prosto: valgrind <nazwa_programu>.

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