web-dev-qa-db-fra.com

Comment bien malloc pour tableau de struct en C

Je vais lire en deux séries de char* (ou chaînes) en utilisant strtok, et puisque ces deux jeux de caractères sont liés, (address : command\n) J'ai décidé d'utiliser une structure.

struct line* array = (struct line*)malloc(sizeof(file) * sizeof(struct line*));

Cette ligne mallocing espace pour la fonction me donne un défaut de segmentation et je me demandais si vous pouvez me dire une bonne façon de malloc espace pour cela. Pour le contexte, voici le reste de mon code:

struct line
{
    char* addr;
    char* inst;
};
while loop{
    x = strtok(line,": ");
    y = strtok(NULL,"\n");
    strcpy(array[i].addr,x); //assume that x and y are always 3characters
    strcpy(array[i].inst,++y);
    i++;
}
12
o0tomato0o

L'allocation fonctionne de la même manière pour tous les types. Si vous devez allouer un tableau de structures line, vous le faites avec:

struct line* array = malloc(number_of_elements * sizeof(struct line));

Dans votre code, vous allouiez un tableau qui avait la taille appropriée pour les pointeurs line, pas pour les structures line. Notez également qu'il n'y a aucune raison de transtyper la valeur de retour de malloc().

Notez que c'est un meilleur style à utiliser:

sizeof(*array)

au lieu de:

sizeof(struct line)

La raison en est que l'allocation fonctionnera toujours comme prévu au cas où vous changeriez le type de array. Dans ce cas, cela est peu probable, mais c'est juste une chose générale à laquelle on doit s'habituer.

Notez également qu'il est possible d'éviter d'avoir à répéter le mot struct encore et encore, en typedefing la structure:

typedef struct line
{
    char* addr;
    char* inst;
} line;

Vous pouvez alors simplement faire:

line* array = malloc(number_of_elements * sizeof(*array));

Bien sûr, n'oubliez pas d'allouer également de la mémoire pour array.addr Et array.inst.

20
Nikos C.

Pour ce que vous avez décrit, Vous n'avez pas besoin d'allouer de mémoire pour votre struct , plutôt , vous devez allouer de la mémoire aux membres char *addr;, et char *inst;. Si vous souhaitez avoir une seule copie de cette structure, la première section de code illustre comment initialiser et affecter des valeurs. Si vous voulez un tableau, le deuxième exemple de code illustre les différences.

Cela illustre comment allouer de la mémoire aux membres d'une ligne de structure unique :

typedef struct
{
    char* addr;
    char* inst;
}LINE;

LINE line;  

int main(void)
{   

    strcpy(line.addr, "anystring"); //will fail
    line.addr = malloc(80);
    line.inst = malloc(80);
    strcpy(line.addr, "someString");//success;
    strcpy(line.inst, "someOtherString");//success;

}

Pour le tableau de la ligne struct ...

typedef struct
{
    char* addr;
    char* inst;
}LINE;  //same struct definition

LINE line[10]; //but create an array of line here.

int main(void)
{   
    int i;

    for(i=0;i<10;i++)
    {
      line[i].addr = malloc(80);
      line[i].inst = malloc(80);
    }

    for(i=0;i<10;i++)
    {
        strcpy(line[i].addr, "someString");
        strcpy(line[i].inst, "someOtherString");
    }
    //when done, free memory
    for(i=0;i<10;i++)
    {
        free(line[i].addr);
        free(line[i].inst);
    }      


}
4
ryyker