【问题标题】:incorrect checksum for freed object - object was probably modified after being freed. how can I fix it?已释放对象的校验和不正确 - 对象在被释放后可能已被修改。我该如何解决?
【发布时间】:2019-05-31 17:02:37
【问题描述】:

运行代码时出现错误:ds(57203,0x70000fba3000) malloc: * 对象 0x7ff875402848 错误:已释放对象的校验和不正确 - 对象在被释放后可能已被修改。 * 在 malloc_error_break 中设置断点进行调试

有时它可以工作,有时它在尝试 malloc 新节点后崩溃(请参阅 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 的文件。

【问题讨论】:

  • 注意:在isEmpty中:检查if (pQueue == NULL)应该返回true,好像没有队列,那么至少它是空的。
  • 当队列中只有一项时检查Dequeue 操作。注意Enqueue中,当队列为空时,设置pQueue-&gt;head = pQueue-&gt;tail = item;
  • 在创建节点时你永远不会初始化指针 prev,因此它们的内容是不确定的,如果你取消引用它们,你会得到未定义的行为。可能不会导致这种情况,但仍然是一个问题。
  • 错误是我之前的评论:item is not dequeued.
  • 维护size 不是正确的方法:当头尾为空时队列为空。保持大小容易出错。

标签: c clion


【解决方案1】:

问题是您分配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) );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 2016-04-25
    • 2015-03-08
    相关资源
    最近更新 更多