Garbage printed with string after strcpy

51 views Asked by At

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.

2

There are 2 answers

0
0___________ On BEST ANSWER
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

5
Vlad from Moscow On

The problem is that you declared a structure with a flexible array member named estado

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

It has an incomplete character array type.

You need either to allocate memory for the data member along with an object of the structure type or to specify a fixed size of the array or declare the data member as a pointer of the type char * and allocate memory for a stored string.

The simplest way is just tp declare the data member estado like

    char estado[3];

It is enough to store your string literals.