• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Tablica jako argument funkcji

Object Storage Arubacloud
0 głosów
929 wizyt
pytanie zadane 15 marca 2020 w Programowanie przez Daaa22 Dyskutant (8,250 p.)

Mam taki kod

void funkcja( int* tab )
{
    return;
}

int main()
{
    int tab[ 3 ] = { 1, 2, 3 };

    funkcja( tab );

    return 0;
}

Czy jest możliwość zapisania tego bez tworzenia zmiennej tab? Bo pisząc taki kod wyskakuje błąd

void funkcja( int* tab )
{
    return;
}

int main()
{
    funkcja( { 1, 2, 3 } );

    return 0;
}

 

3 odpowiedzi

+1 głos
odpowiedź 15 marca 2020 przez mokrowski Mędrzec (155,460 p.)

Oczywiście że jest. W C (bez plusów), w standardzie C99, można stosować wywołanie narzucające typ danych w trakcie wykonania. Reguły wnioskowania domyślnych konwersji do typu docelowego, przekształcają, typ tablicy we wskaźnik na dane. https://en.cppreference.com/w/c/language/array sekcja Array to pointer conversion

#include <stdio.h>

void funkcja( int* tab )
{
    do {
        printf("%d ", *(tab++));
    } while(*tab != 0);
}

int main(void)
{
    funkcja( (int[]){ 1, 2, 3, 0 } );

    return 0;
}

https://en.cppreference.com/w/c/language/compound_literal

Pamięć takiej tablicy alokowana jest w ramach ramki stosu funkcji wywołującej (w tym przypadku main(...) ) i poprawnie usunięta w przypadku zwinięcia ramki https://godbolt.org/z/ShNyY3 Nie następuje tu żadne alokowanie dynamiczne i nie wymaga to również żadnego dealokowania.

Nie jest natomiast to poprawne w C++. Tu od podobnych działań, masz r-referencję.

0 głosów
odpowiedź 15 marca 2020 przez adrian17 Ekspert (344,860 p.)
Nie możesz.

(a czemu potrzebujesz coś takiego?)
komentarz 15 marca 2020 przez Daaa22 Dyskutant (8,250 p.)

Chciałem krócej zapisać. I jak się okazuje jednak mogę

void funkcja( int* tab )
{
    return;
}
 
int main()
{
    funkcja( new int[3]{ 1, 2, 3 } );
 
    return 0;
}

 

komentarz 15 marca 2020 przez adrian17 Ekspert (344,860 p.)
Tylko, że to robi coś innego - alokujesz dynamicznie (a nie na stosie) i w dodatku nie zwalniasz pamięci, więc masz wycieki.
komentarz 15 marca 2020 przez Daaa22 Dyskutant (8,250 p.)
A jak dopisze delete [] tab; w środku funkcji to nie zwolni się pamięć?
komentarz 15 marca 2020 przez adrian17 Ekspert (344,860 p.)
Zwolni się... tylko że to bardzo niezalecany sposób zarządzania pamięcią; ogólnie to jest dużo skompilkowania, plus marnowanie czasu i pamięci programu bo z jakiegoś powodu nie chcesz zrobić zwykłej zmiennej.
komentarz 15 marca 2020 przez Daaa22 Dyskutant (8,250 p.)
Czyli w sumie to kod jest dobry tylko bardzo nieczytelny?
komentarz 15 marca 2020 przez adrian17 Ekspert (344,860 p.)
Technicznie poprawny, ale bardzo odradzany.

(wciąż nie wiem, czemu koniecznie chcesz ominąć używanie zmiennej)
0 głosów
odpowiedź 15 marca 2020 przez profesorek96 Szeryf (91,420 p.)

To co próbujesz zrobić nie jest poprawne w żaden sposób. Język C++ nie posiada mechanizmu GarbageColector. Jeśli wykonujesz tak kod

void funkcja( int* tab )
{
    return;
}
  
int main()
{
    funkcja( new int[3]{ 1, 2, 3 } );
  
    return 0;
}

Twoja funkcja przyjmuje wskaźnik na int, jest to ok zaś ty w mainie przekazujesz jej dynamicznie zablokowaną tablice. Dokładniej mówiąc operator new alokuje pamięć i zwraca wskaźnik na początek tablicy. Jest to ok do czasu kiedy nie chciałbyś zwolnić, gubisz wskaźnik na tą pamięć. Jeśli używasz operatora new to tak za alokowana pamięć musi zostać zwolniona za pomocą operatora delete. Jeśli tego nie zrobisz masz tak zwany wyciek pamięci.

komentarz 15 marca 2020 przez Daaa22 Dyskutant (8,250 p.)
A w środku funkcji nie można napisać "delete [] tab"?
komentarz 15 marca 2020 przez profesorek96 Szeryf (91,420 p.)
Mnożna napisać czemu by nie. Czemu chcesz tak zrobić ?

Podobne pytania

0 głosów
1 odpowiedź 578 wizyt
pytanie zadane 15 grudnia 2018 w C i C++ przez niezalogowany
0 głosów
3 odpowiedzi 1,696 wizyt
pytanie zadane 31 grudnia 2019 w C i C++ przez Mavimix Dyskutant (8,390 p.)
+1 głos
0 odpowiedzi 447 wizyt
pytanie zadane 2 czerwca 2021 w C i C++ przez Mavimix Dyskutant (8,390 p.)

92,568 zapytań

141,424 odpowiedzi

319,634 komentarzy

61,956 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...