Ich versuche, einen einfachen String-Parser für Benutzereingaben neu zu erstellen. Ich kann die Eingabe String ohne Problem erhalten und bestimmen, wie viele einzelne Strings darin sind, um malloc die richtige Größe zu geben. Anfangs fand ich nicht die Anzahl der Strings in stdin und würde einfach mein String-Array neu zuweisen, um Platz für einen weiteren String zu lassen und dann den neuen String malloc. Jetzt, da ich die Größe habe, glaube ich, dass dies nicht notwendig ist, da ich nur Malloc mit der richtigen Größe bereitstellen kann.Realloc Auswirkungen auf Fgets
(Versuchte mit calloc(), an der gleichen Stelle segfaulted)
Was ich bin verwirrt mit, ist, wenn ich realloc in meinem Code lasse kein Problem (abgesehen von zu wissen, ist es wahrscheinlich, meine Array anpassen in eine unerwünschte Mode). Aber, wenn ich realloc entferne, segmentiert mein Code die sofortige Ausführung von fgets().
Dies ist nur, wo ich den Parser nennen, und meine # enthält. "Appserver.h" hält alle Prototypen und std (lib/Bool/io), string/unistd/limits.h
#include "appserver.h"
int main(int argc, char *argv[])
{
if(argc != 4)
{
exit(0);
}
struct userInput user = { parseInt(*argv[1]), parseInt(*argv[2]), argv[3] };
printf("> ");
char **newArgs = stringParser();
for (int i = 0; newArgs[i] != NULL; i++)
{
free(newArgs[i]);
}
free(newArgs);
}
Unten ist mein Code für den Parser. Wenn ich das realloc unkommentiert belasse, kann ich ohne Probleme durch meinen Code gehen (das Durchlaufen von gdb zeigt "input" mit der ganzen Zeichenkette von stdin), aber wenn ich es auszeichne, segle ich richtig, wenn ich versuche, Benutzereingaben in fgets abzurufen (). Warum wirkt sich das Auskommentieren von realloc() sogar auf fgets() aus?
char **stringParser()
{
char *input;
fgets(input, INT_MAX, stdin);
int size = numberOfStrings(input);
char **inputArray = malloc((size)*(sizeof(char*)));
inputArray[0] = malloc(sizeof(char*));
strcpy(inputArray[0], strtok(input, " "));
for(int i = 1; i < size /*inputArray[i-1] != NULL*/; i++)
{
// inputArray = realloc(inputArray, (i+1)*sizeof(char*));
inputArray[i] = malloc(sizeof(char*));
strcpy(inputArray[i], strtok(NULL, " "));
printf("Inside inputArray[%d]: %s\n", i-1, inputArray[i-1]);
}
return inputArray;
}
Hier ist der Code für meine numberOfStrings() -Methode als auch in dem Fall, dies in wert sein könnte suchen, aber ich auch durch sie mit GDB getreten und es scheint ziemlich konkret.
int numberOfStrings(char *input)
{
int count = 0;
char *tempCopy = malloc(sizeof(char*));
strcpy(tempCopy, input);
char* token = strtok(tempCopy, " ");
while(token != NULL)
{
token = strtok(NULL, " ");
count++;
}
free(tempCopy);
return count;
}
EDIT: Ich wollte ich habe vermieden die meisten Bereiche potenziellen undefinierten Verhalten, um sicherzustellen, followup. Ich habe nichts in Haupt-ändern, so hier sind meine Änderungen in
**stringParser()
char **stringParser()
{
char *input = nextLine(stdin);
int size = numberOfStrings(input, strlen(input));
char **inputArray = calloc(size, sizeof(*inputArray));
char *token = strtok(input, " ");
inputArray[0] = malloc(strlen(token));
strcpy(inputArray[0], token);
for(int i = 1; i < size - 1; i++)
{
token = strtok(NULL, " ");
inputArray[i] = malloc(strlen(token));
strcpy(inputArray[i], token);
}
free(input);
inputArray[size-1] = (char*)NULL;
return inputArray;
}
Die Hauptbereiche des Wandels sind:
- Ich benutze
calloc()
stattmalloc()
, obwohl, wenn mein Verständnis korrekt ist danncalloc(size, sizeof(*inputArray))
verhält sich das gleiche (Ignorieren der '0' oder Müll Wert Initialisierung) alsmalloc((size)*sizeof(*inputArray))
- Ein Freund von mir schrieb eine
*nextLine(FILE *input)
, die mir erlaubt, Zeichen für Zeichen durchzu scannenbis ich entwederEOF
oder'\n'
erreiche. Dies hat den Vorteil, genau die Menge an Speicher zuzuweisen, die ich für die Benutzereingabe benötige. - Ich stelle sicher, dass jeder String in meinem Array nur die notwendige Menge an Speicher zugewiesen wird. (Im Gegensatz zu
sizeof(char*)
wie ich zuvor getan hatte) - Ich habe sichergestellt, einen Null-Abschluss-Wert am Ende meiner String-Array enthalten. (I eine Änderung in numberOfStrings gemacht(), wo habe ich nur noch
count++
vor der return-Anweisung.
Diese Veränderungen haben brachte mir nur zu einem Punkt, wo ich nicht mehr Speicherverluste. Ich darf nicht davon ausgehen, ich habe Ich glaube, ich mache jetzt ein bisschen besser, aber ich werde diesen Beitrag nicht mit ein paar anderen Fragen verstopfen, sondern dieses Update hier lassen, falls jemand das möchte finde es nützlich oder relevant.
Bitte erläutern Sie die Zeile 'char * tempCopy = malloc (sizeof (char *));' –
'fgets (Eingabe, INT_MAX, stdin);': 'Eingabe' ist nicht initialisiert. – BLUEPIXY
@ M.M Ich mag es einfach nicht, rohe Ganzzahlwerte zu setzen, und habe noch keine Möglichkeit implementiert, die genaue Länge des Strings noch zuzuweisen. Oder wenn es einen einfachen eingebauten Weg dafür gibt, habe ich es noch nicht entdeckt. Aus Unwissenheit habe ich gerade Größe (char *) benutzt, da es mir noch keine Probleme bereitet hat. – Drewzillawood