Realloc постоянно терпит неудачу (в C)

Realloc постоянно терпит неудачу после того, как я добавляю 25 символов.

Ошибка:

Несоответствие, обнаруженное ld.so: dl-minimal.c: 116: realloc: Утверждение `ptr == alloc_last_block' не удалось!

char** linePtr = getLinePtr(block, y);
char* tmpPtr = realloc(*linePtr, (strlen(*linePtr) + 1) * sizeof(char));
if (tmpPtr != NULL) {
    *linePtr = tmpPtr;
    strinsert(tmpPtr, ch, x);
}

Я проверяю переменные прямо перед этим, и все кажется в порядке. *linePtr указывает на строку из 24 символов, а strlen(*linePtr) возвращает 24. Адрес, возвращаемый realloc, всегда один и тот же.

Нет жестко запрограммированного числа, поэтому я понятия не имею, почему он всегда терпит неудачу после одного и того же количества символов.

*linePtr было 1 всего одним байтом в начале, и сейчас я каждый раз перераспределяю один дополнительный байт.

Редактировать:

char** getLinePtr(Block* block, int y)
{
    assert(y >= block->start && y <= block->start + block->nb_lines);

    if (y == block->start + block->nb_lines) {
        block->lines = realloc(block->lines, (block->nb_lines + 1) * sizeof(char*));
        *(block->lines + block->nb_lines) = malloc(sizeof(char));
        block->nb_lines++;
    }
    return block->lines + block->nb_lines - 1;
}

Редактировать2:

Вставляя код, я понимаю, что в getLinePtr есть ошибка: она возвращает последнюю строку вместо запрошенной (используя y), но это не должно ничего менять в этой ошибке. И используется только первая строка.


person user1681378    schedule 18.09.2012    source источник
comment
Примечание: вы делаете это перераспределение максимально неэффективным.   -  person    schedule 19.09.2012
comment
Что возвращает getLinePtr()? Как он создает возвращаемое значение?   -  person hmjd    schedule 19.09.2012
comment
Если realloc в block->lines = realloc(block->lines, (block->nb_lines + 1) * sizeof(char*)); терпит неудачу, у вас возникает неприятная утечка памяти и неопределенное поведение при последующем использовании block->lines (прямо или косвенно).   -  person Daniel Fischer    schedule 19.09.2012
comment
Что делает strinsert(tmpPtr, ch, x);? С char* tmpPtr = realloc(*linePtr, (strlen(*linePtr) + 1) * sizeof(char));, если вы ранее не записывали за пределы выделенной области, вы не увеличиваете выделенную память, а либо сохраняете ее постоянной, либо уменьшаете ее, поскольку для строки требуется strlen(s)+1 байта (один для 0-терминатора).   -  person Daniel Fischer    schedule 19.09.2012


Ответы (2)


Вероятно, проблема в том, что указатель, который передается realloc, не является указателем, возвращенным realloc или malloc. В показанном коде отсутствуют несколько фрагментов, чтобы знать это наверняка. Но вы должны убедиться, что getLinePtr возвращает «указатель на выделенный указатель» (я не говорю, что это хороший способ сделать это, но именно так он используется в показанном коде).

person Mark Wilkins    schedule 18.09.2012

Проблема заключалась в том, что мне нужно было перераспределить (strlen(*linePtr) + 2) вместо (strlen(*linePtr) + 1).

strlen возвращает размер строки без завершающего нулевого символа. Поэтому мне нужно добавить 1 для него, и мне нужно добавить 1 для символа, который будет добавлен сразу после него.

Спасибо Дэниелу Фишеру за подсказку.

person user1681378    schedule 19.09.2012