printf вызывает предупреждение EXC_BAD_ACCESS(code=EXC_I386_GPFLT) и зависает во время выполнения

У меня есть функция, состоящая из 3 вложенных циклов for и оператора if, внутри нее у меня есть:

int buffsize = valuex*3;
    //int buffsize = (LEDS+1)*3;
    char buffer[buffsize];
    init_buf(buffer, buffsize);
    // while(counter <= linecount){

    int x = 0;
    int y = 0;
    char *bufpointer=buffer;

    for (x=0; x<=valuex; x++) {

        for (y=0;y<=LEDS; y++) {

            for (int i=0; i<=linecount; i++) {

                if (pixels[i].y==y) {

                    snprintf(bufpointer+=strlen(bufpointer), buffsize, "%s%d%d%d",buffer, pixels[i].r,pixels[i].g, pixels[i].b );
                    printf("buffer contents: %s\n",buffer);


                }

            }
         printf("buffer contents: %s\n",buffer);  //placed for debugging
        }

    }



    /**************** buffer initialiser ********************/

    void init_buf(char *buf, size_t size){
    int i;
    for(i=0; i<size; i++){
        buf[i] = '0'; // int to char conversion
     }
    }

где bufpointer является указателем на буфер массива символов.

Я пытаюсь прочитать целочисленные значения из структуры пикселей [] и добавить их все в один буфер.

моя проблема в том, что я получаю предупреждение в функции printf о том, что: Thread 1: EXC_BAD_ACCESS(code=EXC_I386_GPFLT)

во время выполнения программа работает до оператора printf и зависает там


person msk    schedule 19.06.2014    source источник
comment
Вам нужно будет добавить больше вашего кода (до вызова snprintf), чтобы мы могли видеть, как вы выделяете буфер, и подробности о типе указателя буфера и о том, как он используется. Этих двух строк вне контекста недостаточно, но я предполагаю, что вы либо обращаетесь к памяти, которую вы не выделили, либо где-то уходите за конец буфера.   -  person Ken White    schedule 20.06.2014
comment
Я согласен с Кеном. Например, мне было бы интересно узнать, как инициализируется указанный буфер, и гарантирует ли он, что там всегда есть строка с нулевым завершением. Кроме того, убедитесь, что размер буфера уменьшается до оставшегося места при увеличении указателя буфера?   -  person Christophe    schedule 20.06.2014
comment
Теперь я добавил больше кода, я не уверен, как уменьшить значение buffsize после каждой итерации, я также пытался запустить функцию, используя sprint, поскольку она не требует buffsize в качестве аргумента, но это не удалось с той же проблемой.   -  person msk    schedule 20.06.2014


Ответы (1)


Похоже, вы обращаетесь к памяти после конца одного из ваших массивов.

bufpointer+=strlen(bufpointer) в сочетании с buffsize выглядит подозрительно. Я предполагаю, что вы используете bufpointer для объединения нескольких строк в один буфер, заставляя каждый вызов snprintf начинать запись с нулевого байта, оставленного предыдущим вызовом. В этом случае вторым аргументом snprintf должен быть объем пространства, оставшегося в буфере, а не общий размер буфера. Например, если у вас есть буфер с местом для 100 символов, и первый вызов snprintf записывает десять, то для второго вызова ограничение размера должно быть 90, а не 100.

Вы не разместили достаточно кода, чтобы показать, как инициализируются bufpointer и buffsize и изменяются ли они циклом, поэтому неясно, является ли это причиной вашей проблемы, но я подозреваю, что это так.

person Wyzard    schedule 19.06.2014
comment
bufpointer и buffsize — это константы, которые инициализируются перед запуском любого из циклов, поэтому из того, что вы только что сказали, мой код неверен в том смысле, что buffsize не настраивается на оставшееся пространство, как я могу это сделать? - person msk; 20.06.2014
comment
использовать временный size_t sz=strlen(bufpointer); непосредственно перед snprintf(), где вы можете использовать bufpointer+=sz и buffsize-=sz - person Christophe; 20.06.2014
comment
Когда вы добавляете длину предыдущей строки к bufpointer, вам также нужно вычесть то же число из buffsize. (Обратите внимание, что snprintf возвращает количество записанных символов; вы можете использовать это вместо вызова strlen.) - person Wyzard; 20.06.2014