Ошибка проверки времени выполнения # 2 - стек вокруг переменной 'start' поврежден - PullRequest
0 голосов
/ 15 августа 2011

Я получаю описанную выше проблему отладки из функции readString. Я полагаю, что это как-то связано с тем, как в функции определено «начало». Значение 0x07 в массиве изменяется в зависимости от длины следующей строки. В этой строке должно быть указано «тестирование» в юникоде.

int main(){
    char readbuffer[] = {0x07, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67};
    char *buf = readbuffer;
    uint32_t *stringread = (uint32_t *) malloc(sizeof(uint32_t));
    *stringread = readString(buf);
    }

    uint32_t readString(char *buf)
    {
         uint32_t *start = (uint32_t *) malloc(sizeof(uint32_t));
         int len;

         len = protobuf_readVarint(buf, &buf);
         memcpy (&start, buf, len);
         buf += len;

         return start;

    }

Ответы [ 2 ]

1 голос
/ 15 августа 2011

Петр ответил на ваш вопрос. Кроме того, я бы посоветовал вам использовать

len = max(protobuf_readVarint(buf, &buf),sizeof(uint32_t));

или перехват, когда первый аргумент больше, чем второй, потому что в противном случае вы слишком много пишете в начало аргумента. Также у вас есть утечка памяти, которая может быть исправлена ​​с помощью:

uint32_t readString(char *buf)
{
     uint32_t start;
     int len;

     len = max(protobuf_readVarint(buf, &buf),sizeof(uint32_t));
     memcpy ((void*)&start, buf, len);
     buf += len;

     return start;

}
0 голосов
/ 15 августа 2011

Здесь

     memcpy (&start, buf, len);

вы пытаетесь скопировать содержимое buf в &start (адрес переменной-указателя start, которая фактически является адресом в стеке) вместо start (ссылаясь на адрес буфер памяти start указывает на). Это то, что портит ваш стек.

Кроме этого, в вашем коде есть несколько других мелких проблем:

  • у вас нет проверки границ, поэтому, если len равен> 4, memcpy снова будет молча записывать после конца блока памяти, на который указывает start, что повредит память;
  • Вы выделяете блок памяти в пределах readString(), который вы никогда не free, что приводит к утечке памяти; если вы абсолютно уверены, что len никогда не будет больше 4, было бы проще использовать простую локальную переменную:

     uint32_t start;
     ...
     memcpy (&start, buf, len);
    

    обратите внимание, что в этом случае правильно передать &start в memcpy!

  • buf += len не будет действовать за пределами readString(), поскольку buf передается по значению, поэтому изменения в функции влияют только на его локальную копию, а не на оригинал.
...