2016-05-04 18 views
2

Was bedeutet es: "Kann Variablen nicht sammeln"? Wie kann ich es reparieren ? Es bewirkt, dass der Debugger keine Werte meldet."kann Variable nicht sammeln"?

enter image description here

Ich versuche, meine Funktion und argv neu ordnen ändern

write_argument2(argc, * argv, * string[0]);

Ich werde zu nennen. Meine Variable string ist char **string[100][100]; und vielleicht ist das nicht ideal. Das String-Variable wird argv mit neuen Argumenten aktualisieren:

void write_argument2(int argc, char argv[], char *string[]) { 
    int j = 0; 
    for (j = 0; j < argc; j++) { 
     if (argv[j]) 
      string[j] = strdup(&argv[j]); 
    } 
} 

Aber ich habe etwas falsch gemacht, und es stürzt ab. Der Fehler lautet "kann keine Variablen sammeln" und ein Segmentationsfehler für strdup.

Ich habe auch versucht die folgenden, die auch kompiliert, sondern ein Segmentierungsfehler wird: * string[j] = * strdup(& argv[j]);

Gdb sagt:

GNU gdb (Ubuntu 7.11-0ubuntu1) 7.11 
Copyright (C) 2016 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-linux-gnu". 
Type "show configuration" for configuration details. 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
Find the GDB manual and other documentation resources online at: 
<http://www.gnu.org/software/gdb/documentation/>. 
For help, type "help". 
Type "apropos word" to search for commands related to "word"... 
Reading symbols from ./shell...done. 
(gdb) run 
Starting program: /home/dac/ClionProjects/shell2/openshell/shell 
'PATH' is set to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin. 
$ ls 

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000403b1a in write_argument2 (string=<optimized out>, argv=<optimized out>, 
    argc=<optimized out>) at main.c:147 
147    string[j] = strdup(&argv[j]); 
(gdb) 

ich strcpy stattdessen verwenden sollten oder einige Erklärungen ändern?

Antwort

2

Die argv ist ein Array von Strings (char *argv[]), es ist kein Char-Array. Wenn Ihr String als char string[100][100]; definiert ist, das heißt, seine Lagerung sein Arrays definiert, können Sie wie folgt vorgehen:

void write_argument2(int argc, char *argv[], char string[][100]) { 
    int j = 0; 
    for (j = 0; j < argc; j++) { 
     if (argv[j]) 
      strcpy(string[j], argv[j]); 
    } 
} 

Aber dies unterliegt abstürzen, wenn argv mehr Saiten als die Anzahl der string hat, dass 100 ist, oder jemand Element des argv länger ist als 99. so könnte man auch die dynamische Zuordnung zu tun:

char **write_argument2(int argc, char *argv[]) { 
    char **string = malloc(argc * sizeof(char*)); 
    int j = 0; 
    for (j = 0; j < argc; j++) { 
     if (argv[j]) 
      string[j] = strdup(argv[j]); 
    } 
    return string; 
} 

EDIT: ein Testprogramm hinzufügen, für OP zu demonstrieren:

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

char **write_argument2(int argc, char *argv[]) { 
    char **string = malloc(argc * sizeof(char*)); 
    int j = 0; 
    for (j = 0; j < argc; j++) { 
     if (argv[j]) 
      string[j] = strdup(argv[j]); 
    } 
    return string; 
} 


int main(int argc, char *argv[]) 
{ 
    int i; 
    char **string = write_argument2(argc, argv); 
    for (i = 0; i < argc; i++) { 
     printf("%d: %s\n", i, string[i]); 
    } 
    return 0; 
} 

Aufruf dieses Problem:

$ ./a.out a bb ccc dddd 
0: ./a.out 
1: a 
2: bb 
3: ccc 
4: dddd 
+1

@Montao, dass die Zuweisung falsch ist, 'strlen (strdup (argv [j]))' ist die Länge der Zeichenkette 'argv [j]', es ist nicht die Anzahl der Zeichenfolgen im Array. Warum nicht den Code posten, der die Funktion aufruft? – fluter

+0

'string = write_argument2 (argc, argv);' ist der Code, der die Funktion aufruft. – Montao

+1

@Montao sehe mein Testprogramm, es funktioniert für mich. – fluter