2016-04-11 2 views
0

Программа предназначена для получения первого слова и массива оставшихся слов. Например, если line = "a bb cc dd ee", то key должен быть a, keySet должен быть указателем на массив из {bb,cc,dd,ee}.Память распределения на char **

Я пытаюсь динамически выделить память char** keySet, но keySet вывод всегда ee ee ee ee. Похоже, что keySet не является указателем на первый элемент массива, а указывает на последний элемент. В чем проблема в моей функции?

void allocateKeySet(char* line){ 
    int count = 0; 
    char* token = strtok(line, " "); 
    char key[17]; 
    char tempKey[17]; 
    char** keySet; 

    sscanf(strtok(NULL, " "), " %s", key); 
    keySet = calloc(1, sizeof(char*)); 
    while((token = strtok(NULL, " ")) != NULL){ 
     sscanf(token, " %s", tempKey); 
     keySet[count++] = tempKey; 
     keySet = realloc(keySet, (count+2) * sizeof(char*)); 
    } 

    printf("key: %s\n", key); 
    printf("keySet: "); 
    for(int i = 0; i < count - 1; i++){ 
     printf("%s ", keySet[i]); 
    } 
} 

e.g. линия:

"a bb cc dd ee" 

ожидается выход:

key: a 
keySet: bb cc dd ee 

Мой выход:

key: a 
keySet: ee ee ee ee 
+1

'keySet [count ++] = tempKey;': вы, вероятно, хотите 'str (n) cpy' или' strdup'. В настоящее время 'tempKey' получает переназначение каждый раз, и все элементы' keySet' указывают на * тот же * 'tempKey'. Следовательно, после последнего задания tempKey, все они указывают на «ee». (Обратите внимание, что если вы используете 'strcpy', вам нужно сначала назначить память для' keySet [count ++] ';' strdup' выполняет выделение и присваивание за один раз, но вам придется тестировать 'NULL' в любом случае впоследствии.) – Evert

+0

Вы имеете в виду: 'strdup (keySet [count ++], tempKey)'? –

+0

Почти: 'keySet [count ++] = strdup (tempKey)'. Проведите проверку на 'keySet [count-1]! = NULL' после (маловероятно, но правильная вещь). – Evert

ответ

1

keySet[count++] = tempKey;: Вы, вероятно, хотите str(n)cpy или strdup. В настоящее время tempKey получает переназначение каждый раз, и все keySet элементов указывают на те жеtempKey. Следовательно, после последнего tempKey назначения, все они указывают на "ee". (Обратите внимание, что если вы используете strcpy, вам необходимо назначить памяти для keySet[count++] первого; strdup делает распределение и назначение в одном дыхании, но вы должны проверить NULL в любом случае.) После

Таким образом:

while((token = strtok(NULL, " ")) != NULL){ 
     sscanf(token, " %s", tempKey); 
     keySet[count] = strdup(tempKey); 
     if (keySet[count] == NULL) { 
      perror("memory allocation failure"); 
     } 
     count++; 
     keySet = realloc(keySet, (count+2) * sizeof(char*)); 
    } 

Если вы не можете использовать strdup, вы можете использовать следующие строки вместо этого strdup линии:

keySet[count] = malloc(strlen(tempKey)+1); 
// test for keySet[count] 1= NULL 
strcpy(keySet[count], tempKey) 
count++; 

согласно this answer.

Не забудьте освободить отдельного человека keySet элементов впоследствии.

+0

Если я хочу использовать 'strcpy', как я могу назначить память для' keySet [count ++] '? Что-то вроде 'keySet [count ++] = char [strlen (tempKey)]'? Cuz 'strdup' кажется не в стандартной библиотеке C, и я не могу использовать его в своей домашней работе ... –

+0

Какая ОС вы используете. 'strdup' является стандартом POSIX.1-2001 и находится в большинстве библиотек C. – Evert

+0

Также: http://stackoverflow.com/questions/14020380/strcpy-vs-strdup – Evert

Смежные вопросы