Dynamiczna alokacja pamięci

0

Program się uruchamia lecz po wczytaniu napisu zawiesza. Czy ktoś może mi powiedzieć dlaczego + czy jest jakiś krótsza metoda na zalokowanie pamięci dla wskaźnika char, jeżeli nie wiemy jaka będzie długość wpisanego tekstu przez użytkownika?

#include <iostream>
#include <cstdlib>
#include <ctime>

void wczytajNapis(char* wskaznik){
    //tymczasowa tablica
    char tymczasowa[100];
    std::cin>>tymczasowa;
    int i=0;
    while(tymczasowa[i]!='\0'){
        i++;
    }

    wskaznik = new char[i+1];
    
    for(int j=0; j<i; j++){
        wskaznik[j]=tymczasowa[j];
    }

    // uruchomione jest domyslnie usuwanie stworzonych tablic w funkcji przy wychodzeniu z niej
    delete [] tymczasowa;
}


void wypiszNapis(char* wskaznik){
    std::cout<<wskaznik;
}


int main(){
    char *napis;
    wczytajNapis(napis);
    return 0;
}
 
2

Polecam strdup(), jak nie ma to warto napisać:

char *strdup(const char *str)
  {
   size_t size=strlen(str)+1;
   char *ret=new char[size];
   memcpy(ret,str,size);
   return ret;
  }

pamiętaj że standardowy strdup() zwalniać przez free() zaś ten poprzez delete[]

2

Ło Panie (:

Najpierw błędy

void wczytajNapis(char* wskaznik){...}
...
int main()
{
    char *napis;
    wczytajNapis(napis);
}

Takie coś nie zmieni wskaźnika napis w mainie. W parametrze przekazujesz tylko jego kopie.

void wczytajNapis(char* wskaznik){
    char tymczasowa[100];
    ....
    delete [] tymczasowa;
}

Trochę WTF. Po co ten delete?

while(tymczasowa[i]!='\0'){
        i++;
    }

czemu nie strlen?

wskaznik = new char[i+1];

wyciek pamięci bo, tak jak pisałem wyżej, nie przypisujesz tego do tego wskaźnika w main. A nawet jeśli to miałbyś dalej wycieki bo w mainie nawet nie próbujesz zwolnić pamięci.

std::cin>>tymczasowa;

Takie coś jest niebezbieczne bo nie ma kontroli nad długością wczytanego napisu i możesz pisać poza tablicę.

Zbędne includy.

No i poprawna forma wg. Twoich standardów:

void wczytajNapis(char** wskaznik){
    //tymczasowa tablica
    char tymczasowa[100];
    std::cin>>tymczasowa;
    int i=0;
    while(tymczasowa[i]!='\0'){
        i++;
    }
 
    *wskaznik = new char[i+1];
 
    for(int j=0; j<=i; j++){
        (*wskaznik)[j]=tymczasowa[j];
    }
}
 
 
void wypiszNapis(char* wskaznik){
    std::cout<<wskaznik;
}
 
 
int main(){
    char *napis;
	
    wczytajNapis(&napis);
	
    delete [] napis;
	
    return 0;
}

Poprawna forma C++, ale dalej zachowując Twoje rzeczy

std::string wczytajNapis(){
	std::string tmp;
	
    std::cin >> tmp;
	
	return tmp;
}

void wypiszNapis(const std::string &napis){
    std::cout<<napis;
}
 
int main(){
    std::string napis;
	
    napis = wczytajNapis();
    wypiszNapis(napis);
	
    return 0;
}
0

Czy przekazując oryginał wskaźnika muszę używać wskaźnika na wskaźnik? Referencyjnie nie mogę tego wskaźnika przesłać do funkcji?

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