Alokacja dynamiczna dwuwymiarowej tablicy struktur

0

Hej,

Zagadnienie jest takie. Mam globalną strukturę:

struct reg 
{
  char[2] range;
  int number;
  char[4] ID
  char[5] type;
}

Ilość wierszy oraz kolumn per wiersz (może być tak, że jeden wiersz będzie miał 10, drugi 1000 kolumn) jest określona w plikach konfiguracyjnych, które program ładuje, dlatego muszę zadeklarować tablicę tych struktur jako dwuwymiarowy pointer i zrobić alokację po odczytaniu zawartości plików. Mam tak zadeklarowaną tablicę:

  struct reg **registers;

Mając ilość wierszy oraz kolumn per wiersz, chciałbym zaalokować odpowiednią ilość pamięci, ale niespecjalnie wiem jak - co innego alokacja prostego stringa, co innego dwuwymiarowa tablica wskaźników.

K

1
registers=(**reg)malloc(RowCount*sizeof(*reg));
registers[row]=(*reg)malloc(ColCount[row]*sizeof(reg));
0
_13th_Dragon napisał(a):
registers=(**reg)malloc(RowCount*sizeof(*reg));

Identifier "reg" is undefined

0
kal800 napisał(a):

Identifier "reg" is undefined

Więc to:

kal800 napisał(a):

Mam globalną strukturę:

struct reg 
{
  char[2] range;
  int number;
  char[4] ID
  char[5] type;
};

Kłamstwo!

Człowieku, to nie zamiast ...

0

Mam deklarację w zmiennych globalnych:

struct reg
{
    char range[2];
    int number;
    char ID[4];
    char type[5];
};

struct reg **registers;

I alokację w funkcji:

void get_registers(int len)
{
    registers = (**reg)malloc(len * sizeof(*reg));

}

Powinno wszystko grać...

1

https://wandbox.org/permlink/ktsqg27KDrddnreY

wystarczy wywalić sporo kodu i podmienić double na struct reg.

Przeniesione na godbold: https://godbolt.org/z/cqxEdTcvr

0

W języku C sama nazwa struktury nie jest traktowana jako typ. Musisz użyć struct reg zamiast reg wszędzie, gdzie się do tego odnosisz, także tu:

void get_registers(int len)
{
    registers = (** struct reg)malloc(len * sizeof(* struct reg));

}

Żeby to uprościć, możesz przy definicji struktury użyć typedef:

typedef struct
{
    char range[2];
    int number;
    char ID[4];
    char type[5];
} reg;

I wtedy możesz używać reg jako typ, bez dodawania 'struct' za każdym razem.

0

Dzięki bardzo.

Wygląda na to, że wszystko działa. Natomiast mam pytanko - jak można określić potem ilość kolumn per wiersz - próbowałem w taki sposób:

int reg_number = sizeof(*registers[index]) / sizeof(struct reg);

Wychodzi mi wartość 1 - zarówno dzielna jak i dzielnik mają wartość 20 w tym przypadku...

1
kal800 napisał(a):

Dzięki bardzo.

Wygląda na to, że wszystko działa. Natomiast mam pytanko - jak można określić potem ilość kolumn per wiersz - próbowałem w taki sposób:

int reg_number = sizeof(*registers[index]) / sizeof(struct reg);

tak to się nie da. Musisz sobie zapamiętać w dodatkowych zmiennych ile elementów zaalokowałeś w malloc

0
jvoytech napisał(a):
kal800 napisał(a):

Dzięki bardzo.

Wygląda na to, że wszystko działa. Natomiast mam pytanko - jak można określić potem ilość kolumn per wiersz - próbowałem w taki sposób:

int reg_number = sizeof(*registers[index]) / sizeof(struct reg);

tak to się nie da. Musisz sobie zapamiętać w dodatkowych zmiennych ile elementów zaalokowałeś w malloc

Tak. Już wiem - sizeof daje wynik w momencie kompilacji a nie runtime.

Powrót do C z C# bywa ciężki...

1

@kal800:

Zabawy sizeofem to jedno, a dobre zaplanowanie struktury pod podobne zagadnienia, to drugie.
Zaleca się projektować struktury od najdłuższych typów, o potencjalnie największych kaprysach do do alligmentu (długie integery, coraz krótsze, znaki, parzyste tablice lepsze niż nieparzyste)

Sizoef z tej struktury może zaskoczyć, np bawiąc się opcjami kompilatora / kompilatorami

0
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

struct reg {

  int slowianie;

};

struct reg **myreg = NULL;

void fail_function( const char *const estr)  {
	
  perror( estr );
  exit( EXIT_FAILURE );
	
}


int main(void) {

  size_t myreg_len = 15;

  // koniecznie odwołuj się do zmiennej w sizeof 
  myreg = malloc(  myreg_len * sizeof *myreg );
  if( myreg == NULL )  fail_function( "Can't alloc myreg" );

  for( size_t i = 0; i < myreg_len; i++ )  {

    myreg[i] = malloc( sizeof **myreg );
    if( myreg[i] == NULL )  fail_function( "Can't alloc myreg entry" );
 
  }

  return 0;
  
}

EDIT:
troszkę nieuważnie czytałem co autor chce ale zostawiam ten zły przykład bo i tak nie jest taki zły.
Zrozumiałem, że ma być tablica pointerów po prostu pod którymi jest jeden entry. ;-)
Vide *tab[1000] np.

1
ksh napisał(a):
    myreg[i] = malloc( sizeof **myreg );

Doprawdy?

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