Как избежать переполнения буфера с массивом строк C struct - PullRequest
1 голос
/ 26 сентября 2019

Я сталкиваюсь с переполнением буфера при чтении файла на C и копировании символьных массивов.Есть три потенциально нарушающих кода, и я не могу понять, где я ошибаюсь.

Первый читает файл и заполняет его в хэш-карту:

bool load_file(const char* in_file, hmap hashtable[]) {

    for(int x = 0; x < HASH_SIZE; x++) {
        hashtable[x] = NULL;
    }

    FILE *fptr = fopen(in_file, "r");

    char c[LENGTH] = "";
    c[0] = '\0';

    while (fgets(c, sizeof(c)-1, fptr) != NULL) {

        node *n = malloc(sizeof(node));
        hmap new_node = n;      
        new_node->next = NULL;
        strncpy(new_node->content, c, LENGTH-1);

        // do stuff to put it into the hashtable
    }

    fclose(fptr);
    return true;
}

вторая проверяет, находится ли данное содержимое в хэш-карте:

bool check_content(const char* content, hmap hashtable[]) {

    char c_content[LENGTH] = "";
    strncpy(c_content, content, LENGTH-1);

    // do stuff to check if it's in the hashmap

    return false;
}

, а третья анализирует данный файл и проверяет, находится ли его содержимое в хеш-карте:

int check_file(FILE* fp, hmap hashtable[], char * not_found[]) {

    int num_not_found = 0;
    char c[1000] = "";

    while (fgets(c, sizeof(c)-1, fp) != NULL) {

        char * pch;
        char curToken[LENGTH] = "";

        pch = strtok (c," ");
        strncpy(curToken, pch, LENGTH-1);
        curToken[LENGTH]=0;

        if(!check_content(curToken, hashtable)) {
            not_found[num_not_found] = malloc(LENGTH*sizeof(not_found[num_not_found]));
            strncpy(not_found[num_not_found], curToken, LENGTH-1);
            num_not_found++;
        }
    }
    fclose(fp);
    return num_not_found;
}

Наконец, main вызывает ихи освобождает mallocs:

int main (int argc, char *argv[])
{   
    hmap hashtable[HASH_SIZE];
    load_file(argv[2], hashtable);

    FILE *fptr = fopen(argv[1], "r");
    char * not_found[MAX_ENTRIES];
    int num_not_found = check_file(fptr, hashtable, not_found);

    for(int x=0; x<num_not_found; x++) {
        free(not_found[x]);
    }

    for(int y=0; hashtable[y] != NULL; y++) {
        free(hashtable[y]);
    }

  return 0;
}

Мой вопрос таков: что я сделал для каждого из трех фрагментов кода, что вызывает переполнение буфера?Большое спасибо заранее!

1 Ответ

0 голосов
/ 27 сентября 2019

Я наконец-то избавился от проблем переполнения буфера, в основном, следуя совету Дэвида в комментариях, а также выяснил, что у меня на один malloc больше, чем мне нужно.Исправления:

  1. new_node->next нужен malloc
  2. malloc для new_node->next должен произойти, только если он действительно будет использоваться.
  3. not_found[num_not_found] = malloc(LENGTH*sizeof(not_found[num_not_found])); был неправильным и должен был быть notfound[num_not_found] = malloc(sizeof(char) * (strlen(pch)+1)) (при условии, что pch не был завершен нулем).(Примечание: по какой-то причине на моем компьютере malloc(sizeof(char) * strlen(pch)+1) - это не то же самое, что malloc(strlen(pch)+1))
  4. Возвращение каждого malloc действительно должно быть проверено.
...