Search code examples
cesp32

Returning structs with string values in C


I'm writing a function that will return a struct with two string variables, SSID and password. The functions purpose is to generate an SSID based on mac address data which gets called from a hardware api that updates a pointer to a variable.

The function creates and returns the custom type. When I set one of the string variables manually with quotes, the calling function receives the data fine. However when I set the variable to the value of another variable, it doesn't. What's missing here?

typedef struct {
    char *ssid;
    char *password;
} wifi_auth_t;

typedef wifi_auth_t *wifi_auth;

void getmac( uint8_t *mac ) {
  mac[0] = 0xFF;
  mac[1] = 0xFF;
  mac[2] = 0xFF;
  mac[3] = 0xFF;
  mac[4] = 0xFF;
  mac[5] = 0xEE;
}

wifi_auth_t* wifi_set_ap_details() {
  uint8_t mac[6];
  wifi_auth_t *wifi;
  wifi = (wifi_auth_t *)malloc(sizeof(wifi_auth_t));
  getmac(mac);

  for (int i = 0; i < 6; i++ ) {
    printf("0x%.2X ", mac[i]);
  }
  printf("\n");
  char ssid[20];
  sprintf(ssid, "WifiDevice_%X%X%X", mac[3], mac[4], mac[5]);

  wifi->ssid = ssid;

  printf("%s\n", wifi->ssid);
  wifi->password = "stackoverflow";
  return wifi;
  free(wifi);
}


int main() {
  wifi_auth_t *wifi = wifi_set_ap_details();
  printf("Wifi: %s\n", wifi->ssid);
  printf("Pass: %s\n", wifi->password);

}

Solution

  • I guess you're not familiar with C where you have to manage memory explicitly.

    First, uint8_t mac[6]; and char ssid[20]; don't exist after the function exits, so pointers to them in the allocated wifi struct will point to possibly random stuff. One way to handle this, if you know the size will always be the same, is to specify the actual storate in the struct, as in:

    typedef struct {
        uint8_t mac[6];
        char ssid[20];
    } wifi_auth_t;
    

    Second, when you allocate wifi, you can't free it until the last place it's used, which will be somewhere in the code that calls this function main() in this case). When return is executed, nothing after that point is reached, so the free() won't ever be executed.

    You'll have to change a few other bits, like how mac is set, but that should be minor.