Почему я получаю EXC_BAD_ACCESS с этими функциями C ++? - PullRequest
1 голос
/ 05 февраля 2012

Я делаю домашнее задание и сталкиваюсь с этими проблемами. Я получаю EXC_BAD_ACCESS при вызове allocate ();

void* Pool::allocate() {
    if( free == NULL) {
        this->expandPool();
    }
    void* tmp = free;
    void* mem = malloc(elemSize);
    memcpy(&free,free,sizeof(char*)); //exec bad access right here
    memcpy(tmp,mem,sizeof(elemSize));
    return tmp;
}

Вот мой метод expandPool:

void Pool::expandPool() {
    poolSize++;
    // Is this the first time?
    if(poolSize <= 1)
        pool = new char*[poolSize];
    else {
        char** tmp = new char*[poolSize];
        memcpy(tmp,pool,sizeof(pool));
        delete [] pool;
        pool = tmp;
        delete [] tmp;
    }

    char* tmp = NULL;
    char* tmp2;
    for(int i = 0; i < blockSize; i++) {
        tmp2 = new char;
        memcpy(tmp2,&tmp,sizeof(char*));
        tmp = tmp2;
    }
    pool[poolSize - 1] = tmp;
    free = tmp;
}

Ответы [ 2 ]

2 голосов
/ 05 февраля 2012

Если вы Google EXC_BAD_ACCESS, вы обнаружите, что это потому, что вы обращаетесь к памяти за пределами выделенного блока памяти.Это может быть по нескольким причинам.

Итак, давайте начнем с точки сбоя - memcpy: вы пишете свободному указателю (&free) содержимое свободного (free),и копируем sizeof(char *) байтов.Если предположить, что free объявлено как char *free;, тогда это нормально, поэтому это должно быть содержимое free, с которого вы пишете.

Стилистически, используя memcpy, как это - для копирования значения одного указателя- сбивает с толку.Вам лучше что-то вроде:

free = *(char **)free;

, что эквивалентно вашему:

memcpy(&free,free,sizeof(char*));

Значение sizeof(char*) варьируется в зависимости от системы - 4 на 32-битнойи 8 на 64-битной - поэтому объем выделенного пространства должен быть как минимум настолько большим.

Хорошо, поэтому давайте посмотрим на метод expandPool, чтобы увидеть, что для free установлено в:

tmp2 = new char;

Здесь вы выделяете блок памяти с sizeof(char), равным 1.Это должно быть как минимум:

tmp2 = new char[sizeof(char *)];

ПРИМЕЧАНИЕ. Вызов вашей переменной free переопределит функцию free, поэтому вам нужно будет явно обратиться к этой функции, написав ::free.

Я начну с того, что нарисую диаграмму того, какой должна быть структура памяти пула, и как она будет выглядеть / изменяться (а), когда пусто, (б) при выделении свободного чанка и (с)) при выделении чанка, когда вам нужно расширить пул.Пометьте диаграмму различными переменными (pool, tmp, tmp2 и free).Это даст вам представление о том, что вам нужно делать и как должен выглядеть код.

Хорошее понимание структур данных и алгоритмов (путем создания диаграмм) поможет вам правильно понять код.

1 голос
/ 05 февраля 2012

В вашем коде есть несколько проблем.Одна вещь, которая выделяется для меня - это часть:

pool = tmp;
delete [] tmp;

Для меня это pool указывает на удаленную память.Использование pool позже в коде приводит к неопределенному поведению, которое не может быть объяснено языком.Ошибка в другом месте кода просто ожидаема.

...