简体   繁体   中英

malloc + fgets dynamic allocation

This is my code:

int main(int argc, char *argv[]){
    FILE *fp;
    char *tmp, *tmp2, *user, *pass, *line;
    printf("Inserire utente: "); scanf("%ms", &user); /* scanf %ms alloca dinamicamente la memoria */
    printf("Inserire password: "); scanf("%ms", &pass);
    line = malloc((strlen(user)+strlen(pass)) * sizeof(char)); /* DUBBIOOOOOOOOOO */
    fp = fopen("/home/pol/auth.txt", "r");
    if(fp == NULL){
        printf("Errore apertura file\n");
        return EXIT_FAILURE;
    }
    while(!feof(fp)){
        fgets(line, /* E QUI?? */ , fp);
        tmp = strtok(line, " ");
        tmp2 = strtok(NULL, "\n"); /* con fgets ultimo carattere è \n (se pwd=12 => 12\n) quindi devo tagliare prima di \n */
        if((strcmp(tmp,user) == 0) && (strcmp(tmp2,pass) == 0)){
            printf("USER: %s - PASS: %s\n", tmp, tmp2);
            free(user);
            free(pass);
            return EXIT_SUCCESS;
        }
        else{
            printf("Utente o password errati o non presenti nel DB\n");
            free(user);
            free(pass);
            return EXIT_FAILURE;
        }
    }
    return EXIT_SUCCESS;
}

I would like to know if:

  1. it is correct to write into fgets the value sizeof(line) or not. My doubt is that line contain a pointer so it is always 4 or 8 bytes...
  2. line is right allocated?
  1. No, sizeof(line) will return the size of the pointer. What you really want to do is just

     size_t size_required = strlen(user) + strlen(pass) + 1; /* Don't forget about \\0! */ 

    And then just use that size as the size of line. (BTW: your code does not free line.)

    Edit: Actually, since you ultimately want to read there user + password + 2 token separators searched for by strtok, you want to add extra 3 characters: 1 for terminating \\0, 1 for first separator ' ', and 1 for next separator '\\n'. So that should be:

     size_t size_required = strlen(user) + strlen(pass) + 3; /* Don't forget about \\0! */ 
  2. You should remember, that m specifier for dynamic allocation is a non-standard extension. It won't work on some systems. And you should release user and pass only if their scanf calls return positive value (as in: if they succeed).

  3. Allocation of line is incorrect: you allocate one character too few, so terminating \\0 character won't fit (see above). Note that strlen returns string size excluding the terminating \\0 character.

    Additionally, sizeof(char) is pointless. The standard guarantees that sizeof(char) is exactly 1 (because sizeof does not really return number of bytes, but number of chars required to cover bit representation of an argument).

  4. BONUS You should check tmp and tmp2 for NULL , just in case. Calling strcmp on NULL argument will cause segmentation fault. This is important : if a line read contains user+password longer than provided earlier, a token separator will not be read by fgets, and strtok, unable to find, for example, final '\\n' character, will return NULL.

Q: Is it correct to write into fgets the value sizeof(line)?

A: No :)

Because, as you said, it's only 4 (or 8) bytes.

I'm not at all sure what you're trying to do. Perhaps something like this?

#define MAXLINE 80

char *user, *pass, line[MAXLINE];
scanf ("%s", line);
user = malloc(strlen(line)+1);
strcpy (user, line);
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM