strncpy führt zu segmentation fault
Ich bin einfach nur Herumspielen mit strncpy.
Mein Programm sieht wie folgt aus
typedef struct
{
char from_str[10];
}test;
main ()
{
test s1;
memset(&s1,0,sizeof(test));
char src[10]="himansh";
char dest[10];
memset(dest,0,10);
src[3]='\0';
printf("src is %s and strlen is %d \n",
src,strlen(src));
fflush(stdout);
strncpy(s1.from_str,src,100);
printf("s1.from_str is %s , src is %s \n",
s1.from_str,src);
return 1;
}
Bevor ich hier tun strncpy habe ich nun ein "\0" - Zeichen im "src" - string, die Länge des "src" - string wird eine 3 -, Ziel-array der Größe 10 .Aber in strncpy, habe ich die Anzahl der bytes, die kopiert werden 100.
Das heißt, mein Quell-string ist NULL-terminiert. Jetzt strncpy wie jede string-Funktion sollte versuchen, Sie zu kopieren nur 3 bytes, auch wenn die Anzahl der bytes, die ich mehr als 3 (in diesem Fall 100). Es funktioniert, aber ich bekomme einen segmentation fault zu.
Mein Ergebnis ist unten dargestellt
src is him and strlen is 3
s1.from_str is him , src is him
Segmentation fault (core dumped)
Warum ist das " segmentation fault passiert hier.
Kann einer mir helfen hier.
- Was Sie denken, Sie sollten versuchen zu tun, und was Sie tut sind zwei völlig verschiedene Dinge.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Konnte ich Sie auf den man-Seiten, websites, etc., aber letztlich, was zählt, ist der C-standard selbst. Als Teil der standard-Laufzeitbibliothek, die die Nutzung und das Verhalten ist in C99 definiert-§7.23.2.4 als:
Es ist erhebliche implizite Informationen hier, die wichtigsten sind:
strncpy()
wird NICHT kündigen Sie Ihre Ziel-string mit einem null-Zeichen, falls der Quell-string Länge (nicht einschließlich seiner null-terminator) erfüllt oder übertrifft die angegebene Ziel-Puffer-Länge).Darüber hinaus, obwohl deutlich in der Norm festgelegt sind (siehe oben), fährt er Fort, mich zu verwirren, wie viele Anwender sind sich NICHT bewusst, dass
strncpy()
Schwanz füllt das Ziel, string Puffer mit null Zeichen, bis die angegebene Längen
ist erreicht, wenn der Quell-string-Länge ist weniger als der Ziel-Puffer-Größe. Dies zieht die unausweichliche Schlussfolgerung:Die
strncpy()
API schreiben IMMERn
Zeichen an die Adresse verwiesen wird, die von der Ziel-Puffer.In Ihrem Fall, weil das Ziel-Puffer, der nur 10 chars breit, Sie sind schriftlich 90 zusätzliche Zeichen der Vergangenheit definiert-das Ende der beschreibbaren Speicher, und somit zu Fuß in das land der Undefiniertes Verhalten.
In diesem Punkt müssen Sie sich Fragen: "So was ist der Einsatz?" Es ist eine wohl grundlegende use-case. Es ermöglicht das kopieren von bis zu
n
chars um die target-buffer mit der Vorhersagbarkeit zu wissen, dass Sie nicht überrannt Vergangenheitn
chars. Zeitraum. Letztlich, obwohl, Sie wollen eine null-terminierte Zeichenfolge, so die ordnungsgemäße Verwendung ist dieses:wo
N
ist die hard-Länge derdst
Puffer chars und größer-als-oder-gleich1
. Beachten Sie, dassdst
konnte nur so gut sein, eine dynamisch zugewiesene Speicher Zeiger:Mit dem oben genannten, werden Sie immer haben eine null-terminierte Zeichenfolge an
dst
. Wenn der Quell-string Länge kleiner ist als das angegebene Ziel-Puffer-Länge,strncpy()
Schwanz-füllen Sie den rest der Puffer mit null Zeichen, bis eine Summe von source-chars kopiert + Schwanz gefüllte-null-Zeichen entsprichtn
, und die Letzte Aussage ist redundant. Wenn der Quell-string-Länge ist gleich oder größer als die Ziel-Puffer-Länge,strncpy()
stoppen kopieren einmalN-1
chars sind erreicht, und die Letzte Anweisung setzt ein Nullzeichen an das Ende des Puffers. Dies führt zu einer "cut-down" - Präfix-string, der die ursprüngliche Quelle, aber die meisten wichtig, damit Sie NICHT überschreiten die Grenzen Ihres Ziel-Puffer mit einem späteren string-API-Aufruf, der scans für einen terminator.Die Nützlichkeit der oben genannten Technik ist immer fraglich. Ich bin ein C++ Mann, so
std::string
spart mein glücklich-selbst von all dieser Wahnsinn. Aber die Realität ist diese: Manchmal egal, wennsrc
nicht kopiert Gesamtheit zudst
; manchmal nicht. Die Nützlichkeit ist sehr situativ abhängig. Für die Darstellung von string-Daten in einem UI-das wird nicht (wahrscheinlich) egal. Zum kopieren einer Zeichenkette verwendet werden, für die kritischen Daten, die eine partielle-Präfix-substring ist nicht akzeptabel. Wenn die Polizei einen Haftbefehl zu "Joseph Johnson Jr", gibt es einiges zu erklären, wenn sein Vater ("Joseph Johnson") gezogen wird, in den Knast, weil der name-Puffer von der warrant-Emission-software hielt nur 15 chars.Alle gesagt, Ihre "segmentation fault" kommt zu dieser Aussage:
Erinnern an die mutige Aussage oben: "
strncpy()
IMMER schreibenn
Zeichen an die Adresse verwiesen wird, die von der Ziel-Puffer.". Dies bedeutet, dass der obige code wird immer schreiben 100 chars auf den Ziel-Puffer, der in Ihrem Fall ist nur 10 chars weit, so undefiniert Verhalten und wahrscheinlich ker-boom.Dies beheben, indem Sie Folgendes tun, wenn der Ziel-Puffer ist ein fixed-length character-array:
Sehen, die vor der Verwendung für Sie, wie dies für dynamische string der Länge `N chars.
strncpy
ist für die Einreichung in festen Größe der Felder vorhersehbar. Es ist nicht "string-handling-Funktion".Vom http://www.cplusplus.com/reference/cstring/strncpy/
Also wenn der Quell-string-Länge ist kleiner als die Größe der Ziel-Puffer-Größe, noch durch das hinscheiden Verhalten von strncpy, es versucht zu überlagern, der rest der Charaktere außerhalb der Ziel-Puffer-Größe verursacht einen Segmentation fault
Nicht kopiert, sondern über die 100-Zeichen' sollte die Größe entspricht der maximalen zulässigen Größe in der Ziel-Puffer, so könnten Sie geschrieben haben
oder besser zu schreiben, ein
_countof
makroFinden Sie unter: http://www.manpagez.com/man/3/strncpy/
Den stpncpy() und strncpy () - Funktionen kopieren höchstens n Zeichen aus s2
in s1. Wenn s2 kleiner als n Zeichen ist, wird der Rest von s1 ist
gefüllt mit `\0' - Zeichen. Ansonsten ist s1 nicht beendet.
Der Rest ist gefüllt....
Also:
strncpy(s1.from_str,src,100);
Warum verwenden Sie
100
in Ihrer Funktion, from_str und src-beide haben 10 aufeinander folgende bytes reserviert, aber Sie sind das kopieren von 100 Byte an, was zu seg. Schuld.verwenden wie diese,
strncpy(s1.from_str,src,10);
undefined behaviour
erhalten Sie möglicherweise nicht seg Schuld auf andere LINUX-Maschine, aber es ist besser, Sie verwendenstrcpy
in Ihrem Fall.