Unexpected behaviour using String, const char*, and c_str()

Please can someone explain what on earth is going on here?

#include <WiFi.h>
#include <Preferences.h>

Preferences preferences;
const char* ssid     = "empty";
const char* password = "empty";

void setup()
{
    Serial.begin(115200);

    preferences.begin("credentials", false);

    String saved_ssid = preferences.getString("ssid", "");
    String saved_password = preferences.getString("pw", "");
    
    ssid = preferences.getString("ssid", "").c_str();
    password = preferences.getString("pw", "").c_str();

    Serial.println(saved_ssid);
    Serial.println(saved_password);
    Serial.println(ssid);
    Serial.println(password);

    preferences.end();
}

Output:

My SSID
My Password
My Password
My Password

I'm trying to use WiFi.begin(ssid, password); but get an error:

error: no matching function for call to 'WiFiClass::begin(String&, String&)'

So I tried to convert my string to something more appropriate and end up with some strange behaviour.

I recommend changing your thread title so it might attract some specific help. e.g. "Problem with Strings" or something like that... thank you!

The documentation quotes:

When you modify the String object, or when it is destroyed, any pointer previously returned by c_str() becomes invalid and should not be used any longer.

I have a feeling it's something to do with this.

Indeed, the pointers becomes stale when the memory is released.
this won't do.

reserve some space for the SSID and PWD (char arrays) and use strncpy() to copy the content of the preferences into those cStrings

(or just use the preferences to keep track of those)

Why don't you just do this?

WiFi.begin(saved_ssid.c_str(), saved_password.c_str());

Try this and see what you get:

    String saved_ssid = preferences.getString("ssid", "");
    String saved_password = preferences.getString("pw", "");
    
    ssid = saved_ssid.c_str();
    password = saved_password.c_str();

Obviously caused by begin() not accepting String, this post https://forum.arduino.cc/t/wifi-begin-to-strings/381542 suggests something in the form of:

WiFi.begin(saved_ssid.c_str(), saved_password.c_str());

< edit > I see someone already posted that while I was typing