Ich verwende derzeit eine Routine String_concat(char *str1, char *str2)
, die, wie der Name schon sagt, zwei Strings verkettet. Zu diesem Zweck reserviert diese Routine dynamisch Speicher auf dem Heap (über malloc()
). Da die zurückgegebene Zeichenfolge jedoch nur in der aufrufenden Routine verwendet wird, denke ich darüber nach, Speicher auf dem Stack direkt zuzuweisen (über alloca()
). Daher würde ich String_concat()
durch etwas wie String_concat2(char* str1, char* str2, char* dest)
ersetzen, das den Zielpuffer (bereits auf dem Stack zugewiesen) übernehmen würde) als Argument. Also meine Frage ist: Ist es in Ordnung für String_concat2()
in den Stapel seiner aufrufenden Routine schreiben, oder muss ich erzwingen inline über __attribute__((always_inline))
?Ist es für ein Unterprogramm sicher, in den Stapel seiner aufrufenden Routine zu schreiben?
Antwort
Es gibt kein Problem für eine Funktion in den Stapelrahmen seiner aufrufenden Funktion zu schreiben.
Zum Beispiel:
void foo(int *ptr) {
*ptr = 7;
}
void bar(void) {
int value;
foo(&value);
}
In dem obigen Code, foo
Funktion zu einer Stelle schreibt, die in dem Stapelrahmen der bar
Funktion ist, die es erfordert.
Ha offensichtlich, Warum habe ich nicht daran gedacht? Vielen Dank ! –
Eine aufgerufene Routine kann immer Werte in ihrem Aufrufer ändern. Aber es sei denn, Sie möchten die Assemblersprache verwenden, um zu simulieren, was der Compiler tut, kann Speicherplatz im Aufrufer-Stack nicht zuordnen, da seine eigenen Variablen bereits da sind.
Wenn Sie ein Array an Ihre Anrufer zurückkommen müssen, die nur zwei tragbare Wege sind:
- Rufenen ordnet mit malloc Speicher und geben Sie die Adresse seiner Anrufer - der Anrufer später den Block Speicher frei
- Anrufer vorge Ordnen Speicher und einen Puffer an den Angerufenen passieren - die Angerufene füllt nur den Puffer und kümmert sich nicht, wo es zugeordnet ist, nicht, ob es überhaupt zugeordnet ist (möglicherweise statischen oder dynamischen Speicher sein)
- 1. Ist es sicher, den Stapel unter esp zu verwenden?
- 2. Ist es möglich, ein Unterprogramm zur Laufzeit in ein anderes Unterprogramm zu übersetzen und zu übergeben?
- 3. Ist es sicher, einen Thread mit Async abzuschießen und den Rahmen seiner Zukunft zu verlassen?
- 4. Wie kann ich den Namen der aufrufenden Funktion ausdrucken, ohne auf den Stapel zu schauen?
- 5. Ist es sicher, auf die Ressource eines aufrufenden Klassenkonstruktors zu zeigen?
- 6. Ist es sicher, denselben CookieContainer für mehrere HttpWebRequests zu verwenden?
- 7. Ist es sicher, updateApplicationContext zu verwenden, um den Keychain-Wert
- 8. Versuchen, den Stapel zu zerschlagen
- 9. Perl dereferencing ein Unterprogramm
- 10. Ist es sicher, ein kopiertes Git Repo zu verwenden?
- 11. Ist es sicher, von StdIn zu lesen und gleichzeitig in StdOut zu schreiben?
- 12. Retrigger ein VB-Unterprogramm, wie Serialisierung der Ausführung?
- 13. Ist es sicher, `release` für das Debuggen zu überschreiben?
- 14. Ist es sicher zu werfen volatile?
- 15. Ist es sicher, kclass.memberProperties für ein unbekanntes Objekt (Any) aufzurufen?
- 16. Ist es sicher, kaufmännische Zeichen für Benutzereingaben zu entblößen?
- 17. Ist es sicher, Capistrano zu benutzen?
- 18. Ist es möglich, ein Betriebssystem komplett in C zu schreiben?
- 19. Ist es möglich, ein selbstzerstörerisches Programm in C zu schreiben?
- 20. Ist es sicher ALGORITHM = INPLACE für MySql zu verwenden?
- 21. Ist es sicher, Makroaufrufe zu verschachteln?
- 22. Ist es sicher, eine FileInfo für eine Datei zu erstellen, in die gerade geschrieben wird?
- 23. Ist ein einfacher Thread für statische Eigenschaften sicher und sicher?
- 24. Ist es sicher, Token für JS Local Storage zu speichern?
- 25. Ist es sicher, das zu löschen?
- 26. ist es sicher zu schreiben Funktion in GNU C mit mehreren Threads verwenden
- 27. Ist es sicher, hypot() zu kaskadieren?
- 28. Anfänger rufen ein Perl-Unterprogramm
- 29. Ist es sicher, BenutzerregEx zu verwenden?
- 30. Es ist immer sicher unsafeCoerce für gültige Gleichheiten zu verwenden?
C11 Normentwurf n1570: * 6.2.4 Speicherdauern o f objects 2 Die Lebensdauer eines Objekts ist der Teil der Programmausführung, in dem der Speicher garantiert reserviert ist. Ein Objekt existiert, hat eine konstante Adresse, 33) und behält seinen letzten gespeicherten Wert während seiner gesamten Lebensdauer bei. 34) Wenn ein Objekt außerhalb seiner Lebensdauer bezeichnet wird, ist das Verhalten nicht definiert. Der Wert eines Zeigers wird unbestimmt, wenn das Objekt, auf das er zeigt (oder gerade erst), das Ende seiner Lebensdauer erreicht. * – EOF
Später im Projekt, wenn Sie die Funktion verwenden möchten, um Zeichenfolgen zu erzeugen, die nur * nicht * verwendet werden in der Anruffunktion, was dann? Dies scheint ein Fall vorzeitiger Optimierung zu sein, der einfach nicht benötigt wird und nicht sehr zukunftssicher ist. –
Möchten Sie dies aus Leistungsgründen tun? Weil das wie eine wirklich starke Kopplung zwischen den Routinen aussieht, und ich denke, das ist fast immer eine schlechte Sache ... –