Gibt es einen Weg (in reinem C), eine malloc
ed-Zeichenkette von einem Zeichenkettenliteral zu unterscheiden, ohne zu wissen, welche welche ist? Streng genommen versuche ich einen Weg zu finden, um eine Variable zu überprüfen, ob es eine Malloced-String ist oder nicht, und wenn es so ist, werde ich es freigeben. Wenn nicht, werde ich es gehen lassen.
Natürlich kann ich den Code rückwärts graben und sicherstellen, dass die Variable malloc
ed ist oder nicht, aber nur für den Fall, dass es einen einfachen Weg gibt ...
edit: Zeilen hinzugefügt, um die Frage spezifischer zu machen.
%Vor%Gibt es einen Weg (in reinem C), eine Malloced-Zeichenfolge von einem String-Literal zu unterscheiden,
Nicht in irgendeiner tragbaren Weise, nein. Kein Grund zur Sorge. es gibt bessere Alternativen.
Wenn Sie Code in C schreiben, tun Sie dies, während Sie starke Garantien darüber abgeben, wer den Speicher besitzt. Besitzt der Anrufer es? Dann liegt es in ihrer Verantwortung, sie aufzuheben. Hat der Angerufene es? Ähnliche Sache.
Sie schreiben Code, der sehr klar ist in Bezug auf die Kette des Sorgerechts und des Besitzes, und Sie stoßen nicht auf Probleme wie "Wer entzieht das?" Sie sollten nicht das Bedürfnis haben zu sagen:
%Vor%Die Lösung ist; vergiss nicht! Sie haben die Kontrolle über Ihren Code, schauen Sie einfach die Seite ein wenig nach. Entwerfen Sie es als kugelsicher gegen undichte Erinnerungen an andere Funktionen ohne ein klares Verständnis, dass "Hey, Sie können dieses Ding lesen, aber es gibt keine Garantien, dass es nach X oder Y gültig sein wird. Es ist nicht Ihre Erinnerung, behandeln Sie sie als solche . "
Oder vielleicht ist es Ihre Erinnerung. Fall in Punkt; Ihr Aufruf an strdup
. strdup
lassen Sie es (über die Dokumentation) wissen, dass es Ihre Verantwortung ist, die Zeichenfolge, die es Ihnen zurückgibt, aufzuheben. Wie Sie das tun, bleibt Ihnen überlassen, aber Sie sollten den Bereich so eng wie möglich begrenzen und ihn nur so kurz wie nötig halten.
Es braucht Zeit und Übung, damit dies zur zweiten Natur wird. Sie werden einige Projekte erstellen, die den Speicher schlecht verarbeiten, bevor Sie gut damit umgehen können. Das ist ok; Deine Fehler am Anfang werden dir genau das beibringen, was nicht zu tun ist, und du wirst es vermeiden, sie in der Zukunft zu wiederholen (hoffentlich!)
Auch, wie @Lasse in den Kommentaren erwähnt wird, müssen Sie sich nicht um s3
kümmern, das ist eine Kopie eines Zeigers , nicht der gesamte Speicherblock. Wenn Sie bei s2
und s3
kostenlos aufrufen, haben Sie ein nicht definiertes Verhalten.
Hier ist ein praktischer Weg:
Obwohl der C-Sprachen-Standard dies nicht vorschreibt, generiert der Compiler für alle identischen Vorkommen einer gegebenen literalen Zeichenfolge in Ihrem Code eine einzelne Kopie innerhalb des RO-Datenbereichs des ausführbaren Bildes .
Mit anderen Worten, jedes Vorkommen der Zeichenfolge "1234567890"
in Ihrem Code wird in die gleiche Speicheradresse übersetzt.
An der Stelle, an der Sie diese Zeichenfolge aufheben möchten, können Sie einfach ihre Adresse mit der Adresse der Literalzeichenfolge "1234567890"
:
Um dies noch einmal zu betonen, wird es nicht vom C-Sprachen-Standard vorgeschrieben, aber es wird praktisch von jedem vernünftigen Compiler der Sprache implementiert.
UPDATE:
Das Obige ist lediglich ein praktischer Trick, der sich direkt auf die vorliegende Frage bezieht (und nicht auf die Motivation hinter dieser Frage).
Genau genommen, wenn Sie einen Punkt in Ihrer Implementierung erreicht haben, bei dem Sie zwischen einer statisch zugewiesenen Zeichenfolge und einer dynamisch zugewiesenen Zeichenfolge unterscheiden müssen, würde ich eher vermuten, dass Ihr ursprüngliches Design irgendwo entlang der Linie fehlerhaft ist / p>