ошибки конкатенации байтов из блока байтов с использованием memcpy - PullRequest
1 голос
/ 01 июля 2010

Иногда работает следующий код, что, вероятно, означает хорошую концепцию, но плохое исполнение.Так как это зависает в зависимости от того, где упали биты, это означает, что я делаю шаг вперед.Я заинтересован в поиске элегантного способа заполнения bufferdata <= 4096 байт из <code>buffer, но по общему признанию, это не так.

РЕДАКТИРОВАТЬ: ошибка, которую я получаю, является неправильным доступом к буферным данным

unsigned char        buffer[4096] = {0};
char *bufferdata;

bufferdata = (char*)malloc(4096 * sizeof(*bufferdata));
if (! bufferdata)
    return false;

while( ... )
{

    // int nextBlock( voidp _buffer, unsigned _length );
    read=nextBlock( buffer, 4096);

    if( read > 0 )
    {
        memcpy(bufferdata+bufferdatawrite,buffer,read);

        if(read == 4096) {

            // let's go for another chunk
            bufferdata = (char*)realloc(bufferdata, ( bufferdatawrite + ( 4096 * sizeof(*bufferdata)) ) );
            if (! bufferdata) {
                printf("failed to realloc\n");
                return false;
            }

        }

    }
    else if( read<0 )
    {
        printf("error.\n");
        break;
    }
    else {
        printf("done.\n");
        break;
    }
}


free(bufferdata);

Ответы [ 2 ]

4 голосов
/ 01 июля 2010

Трудно сказать, где ошибка, здесь и там не хватает некоторого кода.

if(read == 4096) { выглядит как преступник, что если nextBlock вернул 4000 на одной итерации и 97 на следующей?Теперь вам нужно хранить 4097 байт, но вы не перераспределяете буфер для его размещения.

Вам нужно накапливать байты и перераспределять всякий раз, когда вы проходите границу 4096.что-то вроде:

#define CHUNK_SIZE 4096
int total_read = 0;
int buffer_size = CHUNK_SIZE ;
char *bufferdata = malloc(CHUNK_SIZE );
char buffer[CHUNK_SIZE];
while( ... )
{

    // int nextBlock( voidp _buffer, unsigned _length );
    read=nextBlock( buffer, CHUNK_SIZE );

    if( read > 0 )
    {
        total_read += read;
        if(buffer_size < total_read) {
           // let's go for another chunk
            char *tmp_buf;
            tmp_buf= (char*)realloc(bufferdata, buffer_size + CHUNK_SIZE );
            if (! tmp_buf) {
                free(bufferdata);
                printf("failed to realloc\n");
                return false;
            }
            buffer_data = tmp_buf;
            buffer_size += CHUNK_SIZE ;

        }
        memcpy(bufferdata+total_read-read,buffer,read);
      }
      ... 
    }
0 голосов
/ 01 июля 2010

Несколько комментариев:

Пожалуйста, укажите или сравните 4096. Вы обожжетесь, если вам когда-нибудь понадобится изменить это.Цепочка realloc - чрезвычайно неэффективный способ получить буфер.В любом случае, вы могли бы заранее выбрать размер и получить все сразу?возможно нет, но я всегда съеживаюсь, когда вижу realloc ().Я также хотел бы знать, что такое kZipBufferSize и находится ли он в байтах, как остальные ваши показатели.Кроме того, что именно является буфером данных?Я предполагаю, что это исходные данные, но я хотел бы увидеть их декларацию, чтобы убедиться, что это не проблема выравнивания памяти - что-то вроде этого.Или переполнение буфера из-за неправильного размера.

Наконец, вы уверены, что nextBlock не переполняет память, как?Это еще одна точка потенциальной слабости в вашем коде.

...