3 Stimmen

Wie verwandle ich ein const char*, das von einer Funktion zurückgegeben wird, richtig in ein const char** in C?

Kurz gesagt, ich möchte dies tun:

const char **stringPtr = &getString();

Allerdings verstehe ich, dass Sie nicht & auf rvalues. So bin ich mit diesem stecken:

const char *string = getString();
const char **stringPtr = &string;

Ich kann mit zwei Zeilen leben. Bringe ich mit diesem Hack Probleme mit sich? Ich sollte keine Angst haben, dass ich stringPtr aus der Funktion heraus, in der sie deklariert ist, richtig?

Edit: Ich entschuldige mich dafür, dass ich ursprünglich nicht den vollständigen Kontext angegeben habe. Ich habe das Sommerprojekt übernommen, ein Videospiel von Grund auf in C unter Verwendung von OpenGL für die Grafik zu entwickeln. Ich lese Konfigurationsdaten aus einer Textdatei mit libconfig .

Eine der Komfortfunktionen zum Auffinden einer bestimmten Zeichenfolge in Ihrer Konfigurationsdatei sieht folgendermaßen aus:

int config_setting_lookup_string(const config_setting_t *setting,
                                 const char *name, const char **value)
{
  config_setting_t *member = config_setting_get_member(setting, name);
  if(! member)
    return(CONFIG_FALSE);

  if(config_setting_type(member) != CONFIG_TYPE_STRING)
    return(CONFIG_FALSE);

  *value = config_setting_get_string(member);
  return(CONFIG_TRUE);
}

Die Art und Weise, wie dieser Wert zugewiesen wird, bedeutet, dass, wenn Sie der Funktion einen nicht-initialisierten value versucht es, undefinierten Müll zu derefenzieren, was bei mir so ziemlich immer einen Segfault verursacht. Mein derzeitiger Workaround für dieses Problem ist die Initialisierung von value zuerst auf einen anderen Zeiger, etwa so:

const char *dummyPtr;
const char **fileName = &dummyPtr;
config_setting_lookup_string(foo, "bar", fileName);

Ich versuche also herauszufinden, wie ich den letzten Teil der Funktion am besten umschreiben kann, so dass ich diese zweistufige Initialisierung nicht mehr durchführen muss. Ich habe gedacht, dass die geänderte Funktion wie folgt aussehen würde:

int config_setting_lookup_string(const config_setting_t *setting,
                                 const char *name, const char **value)
{
  config_setting_t *member = config_setting_get_member(setting, name);
  if(! member)
    return(CONFIG_FALSE);

  if(config_setting_type(member) != CONFIG_TYPE_STRING)
    return(CONFIG_FALSE);

  const char *string = config_setting_get_string(member);
  value = &string;
  return(CONFIG_TRUE);
}

0voto

Beta Punkte 91455

Mir gefällt die Lösung von nornagon und caf,

const char *fileName;
config_setting_lookup_string(foo, "bar", &fileName);

aber wenn Sie sich ändern können config_setting_lookup_string Sie können es auch so machen:

int config_setting_lookup_string(..., const char *&value)
{
  ...
  const char *string = config_setting_get_string(member);
  value = string;
  ...
}

const char *fileName;
config_setting_lookup_string(foo, "bar", fileName);

0voto

tengfred Punkte 391

Aus den hinzugefügten Informationen geht hervor, dass Sie versuchen, eine Funktion aufzurufen, die eine Zeichenkette über eines der Funktionsargumente zurückgeben möchte. Der beste Weg, dies zu tun, wäre meiner Meinung nach etwas wie:

const char* fileName;
config_setting_lookup_string(..., &fileName);
(...)
return fileName;

Dadurch wird auf dem Stack Platz für ein const char* reserviert. Der Funktionsaufruf füllt den Zeiger mit der Adresse der Zeichenkette, die er zurückgeben will. Dieser Zeigerwert kann dann bei Bedarf aus der Funktion herausgegeben werden (im Gegensatz zum Zeiger auf den Zeiger, der auf den Stack zeigen würde und ungültig wäre, wenn die Funktion zurückkehrt). Beachten Sie, dass die Initialisierung von fileName mit "getString()" vermutlich zu einem Speicherleck führen würde, da der Zeiger auf die zurückgegebene Zeichenkette überschrieben und die Zeichenkette niemals freigegeben würde.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X