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

Ani malloc ani calloc, a realloc!

Object Storage Arubacloud
0 głosów
411 wizyt
pytanie zadane 6 maja 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)
edycja 6 maja 2020 przez Hubertius

Cześc :)

Mam do wykonania zadanie o trochę... dziwnej dla mnie treści. Oto one:

Napisz program, który pobierze od użytkownika tekst dowolnej długości i wyświetli go na ekranie.

W programie nie wolno korzystać z funkcji malloc oraz calloc, a na funkcję realloc został ustawiony limit pojedynczego wywołania na 50 bajtów. Oznacza to, że każdorazowo już wcsześniej przydzieloną pamięć można zwiększyć najwyżej o 50 bajtów.

W przypadku, kiedy nie uda się przydzielić za pierwszym razem pamięci program powinien wyświetlić komunikat Failed to allocate memory i zakończyć działanie z kodem błędu 8, jeżeli nie uda się powiększyć przydzielonego obszaru pamięci, program powinien wyświetlić dotychczasowo pobrany tekst.

Przykładowa interakcja z programem -- sukces:

Podaj tekst: Dolor amet dolorem velit velit ut.⏎
Dolor amet dolorem velit velit ut.⏎
Przykładowa interakcja z programem -- brak pamięci:

Podaj tekst: Ten tekst jest zbyt dlugi i nie miesci sie w pamieci⏎
Failed to allocate memory⏎
Uwaga

W programie nie wolno korzystać z operatora [].

Generalnie podam pierwszy przykładowy test, na którym mi to wyrzucało:

Napisz program, który pobierze od użytkownika tekst dowolnej długości i wyświetli go na ekranie.

W programie nie wolno korzystać z funkcji malloc oraz calloc, a na funkcję realloc został ustawiony limit pojedynczego wywołania na 50 bajtów. Oznacza to, że każdorazowo już wcsześniej przydzieloną pamięć można zwiększyć najwyżej o 50 bajtów.

W przypadku, kiedy nie uda się przydzielić za pierwszym razem pamięci program powinien wyświetlić komunikat Failed to allocate memory i zakończyć działanie z kodem błędu 8, jeżeli nie uda się powiększyć przydzielonego obszaru pamięci, program powinien wyświetlić dotychczasowo pobrany tekst.

Przykładowa interakcja z programem -- sukces:

Podaj tekst: Dolor amet dolorem velit velit ut.⏎
Dolor amet dolorem velit velit ut.⏎
Przykładowa interakcja z programem -- brak pamięci:

Podaj tekst: Ten tekst jest zbyt dlugi i nie miesci sie w pamieci⏎
Failed to allocate memory⏎
Uwaga

W programie nie wolno korzystać z operatora [].

Na podstawie tego trochę "pokminiłem" i zapisałem to w ten sposób:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char * pointer = NULL;
    char * pointer_new_1 = NULL;
    char * pointer_new_2 = NULL;
    char * pointer_new_3 = NULL;
    char * pointer_new_4 = NULL;
    char * pointer_new_5 = NULL;
    char * pointer_new_6 = NULL;
    char * pointer_new_7 = NULL;
    char * pointer_new_8 = NULL;

    pointer_new_1 = (char *) realloc(pointer,sizeof(char) * 50);
    if( pointer_new_1 == NULL )
    {
        printf("Failed to allocate memory");
        return 8;
    }
    pointer_new_2 = (char *) realloc(pointer_new_1,sizeof(char)*50);
    if( pointer_new_2 == NULL )
    {
        free(pointer_new_1);
        printf("Failed to allocate memory");
        return 8;
    }
    pointer_new_3 = (char *) realloc(pointer_new_2,sizeof(char)*50);
    if( pointer_new_3 == NULL )
    {
        free(pointer_new_2);
        printf("Failed to allocate memory");
        return 8;
    }
    pointer_new_4 = (char *) realloc(pointer_new_3,sizeof(char)*50);
    if( pointer_new_4 == NULL )
    {
        free(pointer_new_3);
        printf("Failed to allocate memory");
        return 8;
    }
    pointer_new_5 = (char *) realloc(pointer_new_4,sizeof(char)*50);
    if( pointer_new_5 == NULL )
    {
        free(pointer_new_4);
        printf("Failed to allocate memory");
        return 8;
    }
    pointer_new_6 = (char *) realloc(pointer_new_5,sizeof(char)*50);
    if( pointer_new_6 == NULL )
    {
        free(pointer_new_5);
        printf("Failed to allocate memory");
        return 8;
    }
    pointer_new_7 = (char *) realloc(pointer_new_6,sizeof(char)*50);
    if( pointer_new_7 == NULL )
    {
        free(pointer_new_6);
        printf("Failed to allocate memory");
        return 8;
    }
    pointer_new_8 = (char *) realloc(pointer_new_7,sizeof(char)*50);
     if( pointer_new_8 == NULL )
    {
        free(pointer_new_7);
        printf("Failed to allocate memory");
        return 8;
    }
    printf("Podaj tekst: ");
    scanf(" %399[^\n]",pointer_new_8);
    free(pointer_new_8);
    return 0;
}

Ale to chyba nie jest to (do końca też nie jestem pewien, czy zapisałem to w sposób poprawny). Z góry dziękuję za wszelkie odpowiedzi.  

komentarz 6 maja 2020 przez overcq Pasjonat (21,690 p.)

W przy­pa­d­ku, kie­dy nie uda się przy­dzielić za pier­wszym ra­zem pa­mię­ci program po­wi­nien wy­ś­wie­t­lić ko­mu­ni­kat Fa­iled to al­lo­ca­te me­mo­ry i za­koń­czyć dzia­ła­nie z ko­dem błę­du 8, jeżeli nie uda się po­więk­szyć przy­dzielo­ne­go ob­sza­ru pa­mię­ci, program po­wi­nien wy­ś­wie­t­lić do­ty­ch­cza­so­wo po­bra­ny tek­st.

Powyższy program nie spełnia tego warunku, ponieważ przydzielasz wielokrotnie pamięć.

Użyj pętli do przydzielania pamięci i wczytywania danych.

komentarz 6 maja 2020 przez Hubertius Bywalec (2,970 p.)

Zrobiłem coś takiego:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char * pointer = NULL;
    char * pointer_new = NULL;
    int i;
    printf("Podaj tekst: ");
    pointer_new = (char *) realloc(pointer,sizeof(char) * 50);
    if( pointer_new == NULL )
    {
        printf("Failed to allocate memory");
        return 8;
    }

    for( i = 0; i < 7; i++ )
    {
        scanf(" %50[^\n]",pointer_new);
        if( (strlen(pointer_new) ) < 50 )
        {
            break;
        }
        pointer_new = (char *) realloc(pointer_new,sizeof(char) * 50);
    }
    //printf("\n%d\n",strlen(pointer_new) );
    //printf("%s",pointer_new);
    return 0;
}

Ale to jeszcze nie to. O czym zapomniałem?

komentarz 6 maja 2020 przez j23 Mędrzec (194,920 p.)

W linii 25 przydzielasz dokładnie tyle samo pamięci co wcześniej. Dodatkowo scanf czyta max 50 + 1 znaków, pointer_new ma co najmniej 50 bajtów, czyli jest możliwość pisania  poza obszarem pamięci, a to błąd.

Tak można:

    size_t size = 50;
    size_t offset = 0;

    char* pointer = realloc(NULL, sizeof(char) * size);
    char c;
    
    while ((c = getc(stdin)) != '\n' && c != EOF) {
        *(pointer + offset) = c;
        if(++offset == size) {
            size += 50;
            pointer = realloc(pointer, sizeof(char) * size);
        }
    }
    
    *(pointer + offset) = 0;

 

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 341 wizyt
pytanie zadane 25 sierpnia 2020 w C i C++ przez fortuna Początkujący (310 p.)
0 głosów
1 odpowiedź 621 wizyt
pytanie zadane 25 listopada 2017 w C i C++ przez Krótki Użytkownik (760 p.)
0 głosów
1 odpowiedź 537 wizyt
pytanie zadane 15 listopada 2017 w C i C++ przez kosttek Początkujący (450 p.)

92,568 zapytań

141,420 odpowiedzi

319,622 komentarzy

61,954 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!

...