views:

430

answers:

4

How do I allocate memory for a char variable (not a char pointer) inside a struct?
(Variable names are in portuguese, sorry if it's kinda confusing)

I have this struct:

typedef struct node{
    char rotulo[10], instrucao[1][2][10], flag;
    int simplificado;

    struct node *referencias[2];
    struct node **antecessores;
    int nrAntecessores;

    struct node *ant;
    struct node *prox;
} Estado;

And this is function insere() that sets values read from an input file in a new node:

void Insere(char *rotulo, char instrucao[][2][10], int qtdInstrucao, char flag){
    int i,j;
    Estado *NovoEstado;
    NovoEstado = (Estado*)malloc(sizeof(Estado));
    NovoEstado->prox = NULL;
    NovoEstado->ant = P->ult;
    strcpy(NovoEstado->rotulo, rotulo);
    NovoEstado->flag = flag;
    NovoEstado->antecessores = NULL;
    NovoEstado->nrAntecessores = 0;
    NovoEstado->simplificado = 0;

    for(i=0;i<qtdInstrucao;i++){
     realloc(NovoEstado->instrucao, i+1*sizeof(char[2][10]));
     strcpy(NovoEstado->instrucao[i][0], instrucao[i][0]);
     strcpy(NovoEstado->instrucao[i][1], instrucao[i][1]);
    }
}

This NovoEstado->flag = flag; isn't working...
Right after I set it, if I print NovoEstado->flag i get the right value, but if I put it after that for by the end of the function, when I print NovoEstado->flag I get the first char of NovoEstado->rotulo...
The same happens when I try to print flag in main()...

I figure that's because I'm not properly allocating memory space to flag in Insere(), is that right? And how do I fix it?

I'm pretty sure it's an awful easy question, and that I possibily knew this once, but I forgot and can't find it anywhere... So any help would be very appreciated

EDIT

Following ocdecio's tip I created a pointer to an two-dimensional array, in order to have a dinamic 3 dimensional array.
My goal is to have a "table" like this:

  10 chars | 10 chars  
|__________|__________|
|__________|__________|
|__________|__________|

Where the number of lines is dinamic, but it's always an array of 2 strings of 10 chars.

So now this is what I'm doing in main:

 char estado[127], rotulo[10], strInstrucoes[117], *conjunto = calloc(21, sizeof(char)), flag;
 char (*instrucao)[2][10];

 FILE * entrada;
 Automato *Aut = (Automato*)malloc(sizeof(Automato));

 if((entrada = fopen(argv[1], "r")) != NULL){
  CriaAutomato(Aut);
  while(fgets(estado, 127, entrada)){
   flag = 0;
   sscanf(estado,"%[^:]: %[^;]; %c", rotulo, strInstrucoes, &flag);
   instrucao = calloc(1, sizeof(char[2][10]));
   conjunto = strtok(strInstrucoes,"() ");
   for(i = 0; conjunto != NULL; i++){
    realloc(instrucao, i+1*sizeof(char[2][10]));
    sscanf(conjunto,"%[^,],%s", instrucao[i][0], instrucao[i][1]);
    printf("%s || %d\n", instrucao[i][1], i);
    conjunto = strtok(NULL, "() ");
   }
   Insere(Aut, rotulo, instrucao, i, flag);
   free(instrucao);
  }
  fclose(entrada);

But this isn't working...
This is the input read from file

adsasdfg2: (abc,123) (def,456) (ghi,789);

but even before I call Insere I'm not assigning the right values to instrucao the way I want, as this is the output of that printf

123
454
789

instead of what I'm aiming for

123
456
789

What's wrong?

(before someone asks, this is part of a homework, but not the homework. My task is to make a Deterministic Finite Automata minimizer, this is just a bug I'm getting related to data input)

Thanks a whole lot

+6  A: 

Your problem is likely to be in this line:

realloc(NovoEstado->instrucao, i+1*sizeof(char[2][10]));

There is no need to allocate anything inside your structure because the field instrucao is statically defined by the statement instrucao[1][2][10], it is not a dynamically allocated structure.

Otávio Décio
+1. nicely spotted.
Mitch Wheat
So if I rewrite `instrucao` as a dinamically allocated struct (as I need it to be) it should work?
Gabe
@Gabe - if you do it right, yes.
Otávio Décio
A: 

You don't need to allocate flag. It's a char defined inside the struct (as oppose to a pointer).

Your error is caused by overwriting flag's contents inside the struct during the for loop where you write to NovoEstado->instrucao (i.e. its a memory scribble or overwrite).

Update: as @ocdecio points out, you do not need to realloc inside the loop, as instrucao is also statically allocated.

Mitch Wheat
+1  A: 

I think this line is the problem:

realloc(NovoEstado->instrucao, i+1*sizeof(char[2][10]));

In the structure the instrucao is defined as a chunk of continuous memory but you are now allocating a memory and assigning the pointer.

Try commenting it out, you don't need to allocate memory for that variable.

stefanB
A: 

I don't know the intent of the code, but it's certainly illegal to do the following:

realloc(NovoEstado->instrucao, i+1*sizeof(char[2][10]));

Basically, the containing structure was allocated using malloc, but the inner-member in question is a statically defined array and it can't be rellocated using the heap (because the heap manager tracks only the malloced pointer to node).

typedef struct node{ char rotulo[10], instrucao[1][2][10], flag;

If you wish to resize for instrucao dynamically, you must define it as a pointer type and allocate memory for it separately.