неверная контрольная сумма для освобожденного объекта - объект, вероятно, был изменен после освобождения. как я могу это исправить? - PullRequest
0 голосов
/ 05 января 2019

При выполнении кода я получаю сообщение об ошибке: ds (57203,0x70000fba3000) malloc: * ошибка для объекта 0x7ff875402848: неверная контрольная сумма для освобожденного объекта - объект, вероятно, был изменен после освобождения. * установить точку останова в malloc_error_break для отладки

Иногда это работает, иногда происходит сбой после попытки разместить новый узел (см. Функцию createNode), поэтому я подозреваю, что оттуда исходит ошибка.

Что я делаю не так? Как я могу это исправить?

Я попытался отладить код и изменить несколько malloc, но не смог решить проблему.

Как я уже говорил ранее, я подозреваю, что ошибка в функции createNode.

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <unistd.h>
    #include <dirent.h>
    #include <string.h>


void* threadFunction(void* searchTerm);
void scanDirName(char * path, char * searchTerm);
char* rootSD;
pthread_mutex_t qlock;

struct Node {
    char* data;
    struct Node* next;
};

// Two glboal variables to store address of front and rear nodes.
    struct Node* front = NULL;
    struct Node* rear = NULL;

// To Enqueue an integer
void Enqueue(char* x) {
    pthread_mutex_lock(&qlock);
/*    printf("\nhere\n");*/
    struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    temp->data =x;
    temp->next = NULL;
    if(front == NULL && rear == NULL){
        front = rear = temp;
        pthread_mutex_unlock(&qlock);
        return;
    }
    rear->next = temp;
    rear = temp;
    pthread_mutex_unlock(&qlock);
}

// To Dequeue an integer.
char* Dequeue() {
    pthread_mutex_lock(&qlock);
    struct Node* temp = front;
    if(front == NULL) {
        pthread_mutex_unlock(&qlock);
        return NULL;
    }
    char* data;
    data = front->data;
    if(front == rear) {
        front = rear = NULL;

    }
    else {
        front = front->next;
    }

    free(temp);
    pthread_mutex_unlock(&qlock);
    return data;
}


void Print() {
    struct Node* temp = front;
    while(temp != NULL) {
        printf("%s ",temp->data);
        temp = temp->next;
    }
    printf("\n");
}

void* threadFunction(void* st){

    char* filepath;
    filepath = NULL;
    char* searchTerm;
    searchTerm = (char*)st;

    while (filepath == NULL) {
        filepath = Dequeue();
    }

    printf("about to enter with %s, %s\n",filepath, searchTerm);
    fflush(stdout);
    scanDirName(filepath, searchTerm);
    if (strcmp(filepath,rootSD) != 0)
        free(filepath);
    return (void*)1;


}

void scanDirName(char * path, char * searchTerm){
    DIR * d = opendir(path); // open the path
    char* str3;

    if(d==NULL) return; // if was not able return

;

    struct dirent * dir; // for the directory entries
    while ((dir = readdir(d)) != NULL) // if we were able to read somehting from the directory
    {

        if(dir-> d_type == DT_DIR){ //
            if (dir->d_type == DT_DIR && strcmp(dir->d_name, ".") != 0 & strcmp(dir->d_name, "..") != 0) // if it is a directory
            {
                str3 = malloc(1+strlen("/") + strlen(searchTerm)+ strlen(dir->d_name) );
                if (!str3){
                    return;
                }

                strcpy(str3, path);
                strcat(str3, "/");
                strcat(str3, dir->d_name);
                printf("\n---\n%s\n---\n",str3);
                Enqueue(str3);
                printf("Succ");
            }
        } else if(dir-> d_type == DT_REG){ //
            if(strstr(dir->d_name, searchTerm)){

                printf("%s/%s\n", path, dir->d_name);
            }
        }

    }
    closedir(d); // finally close the directory
}

int main(int argc, char* argv[]){


    if (argc != 4){
        printf("ERROR\n");
        exit(1);
    }
    char* rootSearchDir = argv[1];
    char* searchTerm = argv[2];
    int threadsNumber = atoi(argv[3]);

    pthread_t threadsCollection[threadsNumber];

    rootSD = rootSearchDir;
    Enqueue(rootSearchDir);

    int i;
    for (i=0; i<threadsNumber; i++){
        if(pthread_create(&threadsCollection[i], NULL, threadFunction, (void*)searchTerm)) {

            fprintf(stderr, "Error creating thread\n");
            return 1;

        }
    }

    int rc;

    for (i=0; i<threadsNumber; i++){
        rc = pthread_join((threadsCollection[i]), NULL);
        if(rc) {
            fprintf(stderr, "Error joining thread, %d\n", rc);
            return 1;

        }
    }



}

}

Этот код ищет файлы, в имени которых содержится searchTerm, начиная с корневого каталога поиска, используя потоки.

1 Ответ

0 голосов
/ 05 января 2019

Проблема в том, что вы выделяете размер searchTerm, но копируете path.

Шансы на длину path и длину searchTerm одинаковы меньше. Таким образом, доступ выходит за пределы str3 и вызывает неопределенное поведение.

         str3 = malloc(1+strlen("/") + strlen(searchTerm)+ strlen(dir->d_name) );
            if (!str3){
                return;
            }

            strcpy(str3, path);  //Here
            strcat(str3, "/");
            strcat(str3, dir->d_name);

Для решения выделяем память длиной path.

str3 = malloc(1+strlen("/") + strlen(path)+ strlen(dir->d_name) );
...