Wątek przeniesiony 2018-05-09 18:40 z Algorytmy i struktury danych przez somekind.

Dynamiczna alokacji tablicy struktur

0

Cześć,
Podczas pisania napotkałem pewien problem, a mianowicie nie wiem jak zaalokować dynamicznie pamięci w mojej tablicy struktur.
Oto co napisałem, byłbym bardzo wdzięczny za jakąś pomoc.


#define N 5
struct Pole
{
    int wartość;
    int cena;
} tab[5][5];
int main()
{
    int i, j;

    tab=(int**)malloc(N*sizeof(struct *Pole));
    for(i=0;i<N;i++)
    {
        tab[i]=(int*)malloc(N*sizeof(struct Pole));
    }

 for(i=0; i<N; i++)
        free(tab[i]);
    free(tab);
    return 0;
}
2
#define N 5
struct Pole
{
    int wartość;
    int cena;
};

struct Pole ** tab;

 int main()
{
    int i, j;
    tab=(struct Pole **)malloc(N*sizeof(struct Pole *));
    for(i=0;i<N;i++)
    {
        tab[i]=(struct Pole *)malloc(N*sizeof(struct Pole));
    }

   for(i=0; i<N; i++)
        free(tab[i]);
   free(tab);
    return 0;
}
1

@ST3PA: Ale jak masz tab[5][5] to tablica jest statyczna, jak ją chcesz dynamicznie alokować??? Jak dokładnie(j) brzmi zadanie?

PS. Na temat nie w komentarzach.

0

Program ma dynamicznie alokować pamięć dla wczytanych z pliku danych, do ich zapamiętania należy wykorzystać następującą strukturę danych

struct Pole
{
    int wartość;
    int cena;
} tab[5][5];
1

Program ma dynamicznie alokować pamięć dla wczytanych z pliku danych

W jakim celu, skoro tablica struktur nie jest dynamicznie alokowana i nie można zmienić jej rozmiaru?

Edit: Jak wyglądają przykładowe dane w pliku? Tak będzie łatwiej zrozumieć pytanie.

1

Zadziwiającym jest to, że taka alokacja jest możliwa:

#include<stdlib.h>
#define N 5

struct Pole
{
    int wartosc;
    int cena;
} tab[5][5];

int main()
{
    int i;

    struct Pole **tab = (struct Pole**)malloc(N*sizeof(struct Pole*));
    for(i=0;i<N;i++)
    {
        tab[i]=(struct Pole*)malloc(N*sizeof(struct Pole));
    }

    for(i=0; i<N; i++)
        free(tab[i]);
    free(tab);
    return 0;
}

Valgrind nie wyrzuca żadnych błędów:

==8415== Memcheck, a memory error detector
==8415== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8415== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==8415== Command: ./c_programming
==8415== 
==8415== 
==8415== HEAP SUMMARY:
==8415==     in use at exit: 0 bytes in 0 blocks
==8415==   total heap usage: 6 allocs, 6 frees, 220 bytes allocated
==8415== 
==8415== All heap blocks were freed -- no leaks are possible
==8415== 
==8415== For counts of detected and suppressed errors, rerun with: -v
==8415== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Naturalnie posiadając tak zdefiniowaną strukturę mamy już przydzieloną pamięć i nie trzeba jej dynamicznie alokować. Pisząc w kodzie programu:

#include<stdlib.h>
#define N 5

struct Pole
{
    int wartosc;
    int cena;
} tab[5][5];

int main()
{

    tab[0][0].wartosc = 2;
    tab[0][0].cena = 1;

    tab[4][4].wartosc = 3;
    tab[4][4].cena = 6;
    return 0;
}

...korzystamy z już zaalokowanej pamięci. Oczywiście również o żadnym wycieku pamięci nie może być mowy:

==8451== Memcheck, a memory error detector
==8451== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8451== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==8451== Command: ./c_programming
==8451== 
==8451== 
==8451== HEAP SUMMARY:
==8451==     in use at exit: 0 bytes in 0 blocks
==8451==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==8451== 
==8451== All heap blocks were freed -- no leaks are possible
==8451== 
==8451== For counts of detected and suppressed errors, rerun with: -v
==8451== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Moim zdaniem takie alokowanie pamięci to UB i po takim procederze tab wskazuje na stertę "przesłaniając" wcześniej zaalokowaną statycznie pamięć.. Masz już tablicę 5 x 5 gotową do użytku więc po co chcesz alokować dynamicznie pamięć? Bez sensu.

EDIT: rzecz jasna zmienna lokalna przesłania globalną i nie ma tutaj żadnego UB, co nie zmienia faktu, że to bez sensu :)

0

calosc

0

Doprawdy nie wiem o co tutaj chodzi. Pamięć masz dostępną z góry i nic tylko z niej skorzystać. Jeszcze jakbyś miał podczas działania programu określać jakiej wielkości ma być Sudoku to rozumiem ale tutaj, gdzie rozmiar jest znany podczas kompilacji? Bez sensu.

1

@grzesiek51114: niech mnie ktoś poprawi jeśli się mylę, ale w Twoim przykładzie w pierwszym kodzie nie ma żadnego przysłaniania zaalokowanej pamięci: to zmienna lokalnie deklarowana w funkcji przysłania ta globalną. To żadne UB: struct Pole **tab = (struct Pole**)malloc(N*sizeof(struct Pole*)); - tutaj nowo zadeklarowany tab przysłania globalną tablicę.

1
grzesiek51114 napisał(a):

Zadziwiającym jest to, że taka alokacja jest możliwa:

...

struct Pole
{
int wartosc;
int cena;
} tab[5][5];

int main()
{
int i;

struct Pole **tab = (struct Pole**)malloc(N*sizeof(struct Pole*));

...


Valgrind nie wyrzuca żadnych błędów:

Co ty opowiadasz, tu nie ma nic dziewnego, @grzesiek51114 -- dodałeś struct Pole ** przed tab wewnątrz main i masz teraz dwie RÓŻNE zmienne o tej samej nazwie tab. Teraz jest już dobrze, ale nie o to przecież chodzi autorowi...

1

Moim zdaniem wynika z zadania, że trzeba to zrobić jak napisałem w pierwszym moim poście w tym wątku. :) A to [9][9] jest tylko po to, żeby student wiedział, że takie są wymiary... Innego wyjaśnienia nie widzę. Ale durnowato sformułowane.

0

W treści zadania nr.2 nie ma nic nt dynamicznej alokacji pamięci, a tylko to zadanie jest w całości zaprezentowane w załączniku.

0

To byłoby w ogóle bez sensu, bo przecież nie da się zrobić takiego zapisu z pomyślną kompilacją, nie pisząc wcześniej struct Pole **tab:

tab = (struct Pole**)malloc(N*sizeof(struct Pole*));

Albo błąd w zadaniu albo prowadzący może mieć słabszy dzień i wprowadził celowo studentów w błąd. ;)

0

Skonsultuje to jeszcze z prowadzącym;
Ale takie mam odnośnie tego co część z was pisała, czy taka alokacja faktycznie ma jakiekolwiek praktyczne zastosowanie?

0

Alokacji dynamicznej na już zaalokowanym statycznie obiekcie nie da się zrobić więc praktycznie to nie ma sensu. Albo korzystasz ze statycznej alokacji albo alokujesz dynamicznie.

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