Разбор и манипулирование беззнаковыми символами C-Style в C/C++ - ошибка сегментации

Обратите внимание, что для этого я использую компилятор C++ (следовательно, приведение к вызову функции calloc), но код, по сути, написан на языке C.

По сути, у меня есть от typedef до unsigned char, известного как viByte, который я использую для создания строкового буфера для анализа файла из двоичного (точнее, файла TGA, но это не имеет значения).

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

Проблема в том, что на первой итерации первого цикла в viByteBuf_Prepend я получаю ошибку сегментации. Мне нужно точно знать, почему, поскольку это то, что может не давать мне спать всю ночь без каких-либо указателей (каламбур).

Я также хотел бы знать, правильны ли мои алгоритмы с точки зрения того, как буфер предваряет строку viByte. Например, у меня есть ощущение, что слишком частое использование memset может быть плохой идеей, и правильно ли мой формат printf для unsigned char (у меня такое ощущение, что это не так, поскольку ничего не выводится на мою консоль) .

Компиляция на GCC, Linux.

Код Ze

#ifdef VI_BYTEBUF_DEBUG
void viByteBuf_TestPrepend( void )
{
    viByteBuf* buf = viByteBuf_New( 4 );

    buf->str = ( viByte* ) 0x1;

    printf(" Before viByteBuf_Prepend => %uc ", buf->str);

    viByteBuf_Prepend( buf, 3, ( viByte* ) 0x2 );

    printf(" After viByteBuf_Prepend => %uc ", buf->str);
}
#endif

viByteBuf* viByteBuf_New( unsigned int len )
{
    viByteBuf* buf = ( viByteBuf* ) calloc( sizeof( viByteBuf ), 1 );

    const int buflen = len + 1;

    buf->str = ( viByte* ) calloc( sizeof( viByte ), buflen );
    buf->len = buflen;

    buf->str[ buflen ] = '\0';

    return buf;
}

void viByteBuf_Prepend( viByteBuf* buf, unsigned int len, viByte* str )
{
    unsigned int pos, i;
    const unsigned int totallen = buf->len + len;
    viByteBuf* tmp = viByteBuf_New( totallen );
    viByte* strpos = buf->str;


    memset( tmp->str, 0, tmp->len );

    int index;

    for( i = 0; i < buf->len; ++i )
    {

       index = ( buf->len - i ) - 1;

       *strpos = buf->str[ 0 ];
       ++strpos;
    }

    memset( buf->str, 0, buf->len );

    printf( "%uc\n", buf->str );

    i = totallen;

    for ( pos = 0; pos < len; ++pos )
    {
        tmp->str[ pos ] = str[ pos ];
        tmp->str[ i ]   = buf->str[ i ];

        --i;
    }

    memset( buf->str, 0, buf->len );

    buf->len = tmp->len;

    memcpy( buf->str, tmp->str, tmp->len );

    viByteBuf_Free( tmp );

    //memset(  )
    //realloc( ( viByteBuf* ) buf, sizeof( viByteBuf ) * tmp->len );
}

Большое спасибо.

Обновить

Извините, я должен был явно опубликовать код, в котором лежит ошибка сегментации. Это прямо здесь:

for( i = 0; i < buf->len; ++i )
{

   index = ( buf->len - i ) - 1;

   *strpos = buf->str[ 0 ]; //<--segmentation fault.
   ++strpos;
}

person zeboidlund    schedule 05.03.2012    source источник
comment
Почему вы присваиваете числа, такие как 1 и 2, указателям? Думаете, по адресам 1 и 2 есть что-то особенное?   -  person David Schwartz    schedule 05.03.2012
comment
Пробовали запускать в отладчике? Он сообщит вам точную строку, в которой вы получили ошибку сегментации, и позволит вам проверить переменные, чтобы увидеть, какая из них может быть NULL.   -  person Some programmer dude    schedule 05.03.2012
comment
buf->str[ buflen ] = '\0'; — это переполнение буфера. Если в массиве всего 10 записей, то нет записи с номером 10, потому что есть запись с номером 0.   -  person David Schwartz    schedule 05.03.2012
comment
указание указателя char * на 0x1 или 0x2 означает, что вы мертвы, забудьте обо всем остальном. вы, вероятно, имели в виду установить значение буфера равным 1.   -  person Not_a_Golfer    schedule 05.03.2012
comment
@JoachimPileborg да, я запустил его в отладчике. Я знаю точную строку, в которой я получаю ошибку сегмента, я просто не знаю, почему я получаю эту ошибку сегмента. Я пробовал много разных вещей, чтобы заставить это работать.   -  person zeboidlund    schedule 05.03.2012


Ответы (1)


В вашем коде у вас есть buf->str[ buflen ] = '\0';, но вы выделяете место только для buflen. Я думаю, вы имели в виду buf->str[ len ] = '\0';.

person Fred    schedule 05.03.2012