Удалить элемент из указателя и указатель на указатель в C - PullRequest
0 голосов
/ 12 ноября 2018

Все еще учусь, это сегмент кода, над которым я работаю, и я пытаюсь удалить элемент (ы) из указателя / указателя-указателя.Проблема в конце кода.

int total, tempX = 0;

printf("Input total people:\n");fflush(stdout);
scanf("%d",&total);
printf("You entered:  %i\n", total);

char **nAmer = (char**) malloc(total * sizeof(char*)); //pointer pointer for username
for (tempX=0; tempX<total; tempX++){
   nAmer[tempX] = malloc(21);
}

double *nUmer = (double*) malloc(total* sizeof(double)); //pointer for usernumber

printf("input their name and number:\n");fflush(stdout);

for (tempX = 0; tempX<total; tempX++){
    scanf("%20s %lf", nAmer[tempX], &nUmer[tempX]);
}

printf("Let me read that back:\n");
for (tempX = 0; tempX<total; tempX++){
   printf("Name: %s Number: %lf\n", nAmer[tempX], nUmer[tempX]);
}

char *searcher = (char*) malloc(21 * sizeof(char*)); //temporary string made by the user to compare names
printf("Enter name to remove user(s):\n");fflush(stdout);
scanf("%20s",searcher);
for (tempX = 0; tempX < total; tempX++){
    if (strcmp(searcher,nAmer[tempX])==0){ //what is better to replace this section?
       free(nAmer[tempX]); //I can assume this wont work well
       free(nUmer[tempX]); //I know this is a problem
   }
}
printf("Let me read that back with removed user(s):\n");fflush(stdout);
for (tempX = 0; tempX<total; tempX++){
    printf("Name: %s Number: %lf\n", nAmer[tempX], nUmer[tempX]);
}

Я знаю, что free (nAmer[tempX]); работает, но не допускает считывание после его удаления.Что бы это исправить?

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

У вас есть два варианта.

  1. Измените указатель в nAmer на NULL после того, как вы его освободите, не изменяйте nUmer.Таким образом, при обработке записи в nAmer[i] или nUmer[i] вы можете проверить, действительно ли nAmer[i] (!=NULL) или нет (==NULL), и игнорировать запись, если она недействительна.
  2. Вы можете переместить все записи после удаления одной записи вверх в массиве и помнить, что теперь не существует total количество записей, а только total-1 количество записей.

Пожалуйста, не free(nUmer[i]).Записи в nUmer являются двойными, а не указателями.Вы не можете free их.

0 голосов
/ 12 ноября 2018

Вы не должны free(nUmer[tempX]);, потому что это не указатель.

Когда вы освобождаете один из указателей имени, вы можете установить его на NULL.Затем цикл, который печатает массив, который может пропустить его.

for (tempX = 0; tempX < total; tempX++){
    if (strcmp(searcher,nAmer[tempX])==0){ //what is better to replace this section?
       free(nAmer[tempX]);
       nAmer[tempX] = NULL;
   }
}
printf("Let me read that back with removed user(s):\n");fflush(stdout);
for (tempX = 0; tempX<total; tempX++){
    if (nAmer[tempX]) {
        printf("Name: %s Number: %lf\n", nAmer[tempX], nUmer[tempX]);
    }
}

У вас есть другая ошибка:

char *searcher = (char*) malloc(21 * sizeof(char*)); //temporary string made by the user to compare names

Это должно быть просто * sizeof(char) (или вы можете просто пропустить этопоскольку sizeof(char) определено как 1).

К счастью, это выделяет больше памяти, чем необходимо, а не меньше.

...