Search code examples
cstructstrcpygarbage

Garbage printed with string after strcpy


I am a beginner in C and I am trying to copy a string inside another one. I have the following code:

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

typedef struct {
    float mort_2009, mort_2015, indices;
    char estado[];
} Mortalidade;

void defineEstados (
    Mortalidade *e, 
    char estado[],
    float mort_2009,
    float mort_2015,
    int posix)
{
    strcpy(e[posix].estado, estado);
    e[posix].mort_2009 = mort_2009;
    e[posix].mort_2015 = mort_2015;
    e[posix].indice = mort_2009 / mort_2015;
}

void imprimeEstados (Mortalidade *e){
    for (int i = 0; i < 3; i++){
        printf("Estado: %s, Morte em 2009: %.1f, Morte em 2015: %.1f, Indice: %.2f \n",
            e[i].estado,
            e[i].mort_2009,
            e[i].mort_2015,
            e[i].indice);
    }
}

int main() {

    Mortalidade estados[27];

    defineEstados(estados, "AC", 12.6, 10.6, 0);
    defineEstados(estados, "AL", 12.6, 10.6, 1);
    defineEstados(estados, "AP", 12.6, 10.6, 2);
    
    imprimeEstados(estados);
    return 0;
}

My struct Mortalidade has a field called estado, which will receive a string (and other data) in the void function defineEstados. Therefore, after copying the string inside the struct using strcpy, in the void function imprimeEstados, when I want to print the estados inside my struct, the result seems like garbage inside the variable, and I don't know how to find the error. Here is the output obtained:

Estado: ��IA��)A�&�?��IA��)A�&�?AP, Morte em 2009: 12.6, Morte em 2015: 10.6, Indice: 1.19 
Estado: ��IA��)A�&�?AP, Morte em 2009: 12.6, Morte em 2015: 10.6, Indice: 1.19 
Estado: AP, Morte em 2009: 12.6, Morte em 2015: 10.6, Indice: 1.19  

Speaking personally seems like garbage concatenated, but I don't know how to fix it.

Note: I pretend to insert more estados, but I prefer to fix the code previously.


Solution

  • typedef struct {
        float mort_2009, mort_2015, indices;
        char estado[];
    } Mortalidade;
    

    estado is a flexible array member having length zero (0). You cant use this struct the way you use it in your program as static allocation will not allocate any memory for it.

    This kind of struct is intended to be used with dynamic allocation.

    typedef struct {
        float mort_2009, mort_2015, indices;
        char estado[];
    } Mortalidade;
    
    void defineEstados (
        Mortalidade **e, 
        char estado[],
        float mort_2009,
        float mort_2015,
        int posix)
    {
        e[posix] = malloc(sizeof(**e) + strlen(estado) + 1);
        if(e[posix])
        {
            strcpy(e[posix] -> estado, estado);
            e[posix] -> mort_2009 = mort_2009;
            e[posix] -> mort_2015 = mort_2015;
            e[posix] -> indices = mort_2009 / mort_2015;
        }
    }
    
    void imprimeEstados (Mortalidade **e){
        for (int i = 0; i < 3; i++){
            if(e[i]) printf("Estado: %s, Morte em 2009: %.1f, Morte em 2015: %.1f, Indice: %.2f \n",
                e[i] -> estado,
                e[i] -> mort_2009,
                e[i] -> mort_2015,
                e[i] -> indices);
        }
    }
    
    int main() {
    
        Mortalidade *estados[27];
    
        defineEstados(estados, "AC", 12.6, 10.6, 0);
        defineEstados(estados, "AL", 12.6, 10.6, 1);
        defineEstados(estados, "AP", 12.6, 10.6, 2);
        
        imprimeEstados(estados);
        //free memory
        return 0;
    }
    

    https://godbolt.org/z/13j31hGeG