0

Still learning, this is a segment of code I'm working on and I'm trying to remove an element(s) from a pointer/pointer-pointer. The problem is near the end of the code.

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]);
}

I know free (nAmer[tempX]); works but doesn't allow for the read back after its removal. What would fix this?

  • 1
    Welcome to Stack Overflow! [don't cast malloc](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar Nov 12 '18 at 17:19

2 Answers2

0

You shouldn't free(nUmer[tempX]); because this isn't a pointer.

When you free one of the name pointers, you can set it to NULL. Then the loop that prints the array that can skip it.

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]);
    }
}

You have another mistake:

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

This should just be * sizeof(char) (or you can just leave this out, since sizeof(char) is defined to be 1).

Luckily this allocates more memory than needed, not less.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • you can't remove the `nUmer` element. You don't need to remove it, you just ignore it because the corresponding `nAmer` element is `NULL`. – Barmar Nov 12 '18 at 17:38
  • The null shouldn't be printed, because the `if` skips it. – Barmar Nov 12 '18 at 17:38
  • BTW, a better way to do this would be with an array of pointers to structures, rather than 2 arrays. – Barmar Nov 12 '18 at 17:39
  • yeah didn't notice that if statement, I know about structures and linked lists being better for this, but I wanted to learn more about pointers – Bryan Rosen Nov 12 '18 at 17:43
0

You have two options.

  1. Change the pointer in nAmer to NULL after you freed it, don't change nUmer. That way when processing an entry in nAmer[i] or nUmer[i] you can check if nAmer[i] is valid (!=NULL) or not (==NULL) and ignore the entry if it is invalid.
  2. You can move all entries after the removed entry one up in the array and remember that now there are not total number of entries but only total-1 number of entries.

Please do not free(nUmer[i]). The entries in nUmer are doubles and not pointers. You cannot free them.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69