2017-09-01 2 views
0

Ich habe das unten Programm: (Funktionalität: Pads White Spaces rechts von Zeichenfolge verwendet astreix hier für die visuelle Leichtigkeit):Warum funktioniert das Memset nicht wie erwartet?

Betriebssystem: Windows (Visual Studio)

#include "stdafx.h" 
#include<stdlib.h> 
#include<string.h> 

#define CBUFFSIZE 48 

void right_pad_str(char *pad_str, char *buff,int max_buffsize){ 

    int padstr_len = 0; 
    int space_len = 0; 
    char *end_str = NULL; 

    memset(buff, '\0', max_buffsize); 
    padstr_len = strlen(pad_str); 
    space_len = ((max_buffsize - 1) - padstr_len); 

    strncpy_s(buff, max_buffsize, pad_str, strlen(pad_str)); 

    end_str = buff +padstr_len; 

    memset((end_str), '*', space_len); 

    buff[max_buffsize] = '\0'; 

} 

int _tmain(int argc, _TCHAR* argv[]){ 
    char tmpstr[49] = { '\0' }; 
    char *str = "hello_world"; 

    right_pad_str(str, tmpstr, CBUFFSIZE + 1); 

    return 0; 
} 

Es scheint zu sein, ein Problem bei memset, wenn ich auf den Wert post memeset schaue, sieht es sehr inkorrekt dh Junk, warum ist das? Am Ende ich null die Zeichenfolge zu beenden, aber ich sehe Junk-Wert und einen Stapel Korruption Fehler, nicht sicher, was ist los mit meiner Logik.

(Ich habe einen Schnappschuss der gleichen befestigt)

memset invalid value

+3

"Am Ende ich Null die Zeichenfolge beenden" Ihr Screenshot zeigt, dass die Zeile, die Nul-Terminiert die Zeichenfolge noch nicht ausgeführt hat. – tkausl

+0

Ich null es für zusätzliche Sicherheit beenden Ich Memse es direkt am Anfang, aber ich sehe Müll in der Zeichenfolge –

+1

Ja, aber die Zeichenfolge ist noch nicht null beendet. Es wird eine Zeile später sein. –

Antwort

3

Das unerwartete Verhalten in diesem einfacheren Beispiel gesehen werden kann:

#include <stdio.h> 
#include <string.h> 

int main(int argc, char **argv) 
{ 
    char buffer[3]; 
    buffer[0] = '\0'; 
    buffer[1] = '\0'; 
    buffer[2] = '\0'; 
    strncpy_s(buffer, 3, "*", 1); 
    printf("%u\n", (unsigned int)(unsigned char)buffer[2]); 
    return 0; 
} 

Der Ausgang 254 eher als 0, aber nur in einem Debug-Build. Dies geschieht während des Aufrufs an strncpy_s, der unerwartet nach dem Ende der Kopie in den Zielpuffer schreibt, vermutlich um Bugs wie den (bereits hervorgehobenen) in Ihrem Code zu entdecken.


NB: Retired Ninja ganz richtig darauf hin (in den Kommentaren auf die Frage), dass dies etwas ungenau, in the documentation's feinen Druck beschrieben, die ich ursprünglich übersehen hatte:

Die Debug-Versionen dieser Funktionen füllen zuerst den Puffer mit 0xFD. Verwenden Sie _CrtSetDebugFillThreshold, um dieses Verhalten zu deaktivieren.

(In der Tat, in Visual Studio 2010, zumindest, füllt er den Puffer mit 0xFE.)

+0

Was hat 254 mit 0xFD zu tun? Sieht nach einer Off-by-1-Situation aus. – chux

+1

@chux, meine Vermutung wäre ein Tippfehler in der Dokumentation. –

2

@Harry Johnston feiner Antwort erklärt, was schief gelaufen ist.


ein String seiner Feldgrße PAD empfehlen:

1) Dispense mit dem übermäßigen Schreiben von '\0' (memset(buff, ...);... strncpy_s(buff,...), die mit Daten anschließend geschrieben werden.

2) Verwenden Sie size_t zum Indexieren von Arrays und String math. size_t ist die Ganzzahl der richtigen Größe für den Job.

3) Achten Sie auf schlechte Formularaufrufe wie bei einem Pad, das länger als das Ziel ist, oder auf einen Anruf mit einer Größe von 0. Konnte auch nach NULL Zeigern suchen.

Verwandte Themen