2015-02-05 2 views
-1

Код ниже компилируется правильно, однако при его выполнении на консоли отображается следующая ошибка ... Код исключения: c0000005. ошибка возникает в следующей строке:Язык C/C++ - POINTERS и ARITHMETIC ... Код исключения: c0000005

*cptr++ = hextbl[((tval >> 4) & 0x0F)]; 

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

#include <stdio.h> 

// function prototypes 
int main(int argc, const char *argv[]); 
char *put_hexbyte(char *cptr, char tval); 

// main routine 
int main(int argc, const char *argv[]) // variables to get arguments 
{ 
    char val = 65;  // 0x41 >>> I need 2 bytes 0x34 and 0x31, 
         // they are ASCII from 0x41 (0x34 = "4" and 0x31 = "1") 
    char *bufASCII; // pointer to store these ASCII 

    bufASCII = put_hexbyte(bufASCII, val); 

    return 0; 
} 


// Put a byte as hex ASCII, return pointer to next location. 
char *put_hexbyte(char *cptr, char tval) 
{ 
    static char hextbl[16] = 
    { 
     '0', '1', '2', '3', '4', '5', '6', '7', 
     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 
    }; 

    printf("at this point, all is OK!!!\n"); // <<< OK! 
    *cptr++ = hextbl[((tval >> 4) & 0x0F)]; // <<< memory violation error! (Exception Code: c0000005) 
    *cptr++ = hextbl[tval & 0x0F]; 

    return(cptr); 
} 

Спасибо за вашу помощь! :)

+1

'* cptr ++ = hextbl [((tval >> 4) & 0x0F)];' является одним из самых запутанных и запутанных способов индексирования массива, который я когда-либо видел. – CoryKramer

+2

Какая * действительная * память указывает 'cptr' на то, когда вы входите в функцию и начинаете разыгрывать ее? Это более фундаментально, чем арифметика указателя. – molbdnilo

+0

@molbdnilo Ваш комментарий на самом деле отвечает на вопрос. Но только если кто-то захочет увидеть его воспалительный стиль и только для людей, которые уже понимают, как работают указатели на C. – anatolyg

ответ

5

Ваш указатель:

char *bufASCII; 

ли неиницализированные. А потом писать:

*cptr++ = x; 

Вы должны инициализировать его первым, в противном случае, используя это неопределенное поведение. Например:

char *bufASCII = new char[2]; 

Хотя даже тогда, это:

bufASCII = put_hexbyte(bufASCII, val); 

потеряет след исходного указателя. Если вы хотите, возвращаемое значение для конца буфера, вы должны хранить эти separateyl:

char* eob = put_hexbyte(bufASCII, val); 
+0

Стоит отметить, что указатель на конец буфера находится рядом с бесполезным - буфер слишком короткий, чтобы добавить что-либо к нему (например, '' \ 0''). Возможно, вам следует выделить еще несколько (не знаю, сколько) или просто использовать 'std :: string' (вопрос помечен C++, но этот тег кажется несущественным). – anatolyg

+0

@anatolyg, спасибо ... наконечник Барри, работал очень хорошо! И теперь, когда я понимаю, как подготовить указатель, я могу делать другие вещи, которые мне нужны, с большим размером. :) – songa

+0

@Barry, спасибо большое за вас !!! Один, чтобы решить мой вопрос, а другой - в начале (оригинальной) подсказке! Его ответ был коротким (правильный размер), вежливым и эффективным. :) – songa

3

Это:

char *bufASCII; // pointer to store these ASCII 

является указателем на символ, но это на самом деле не указывает ни на что пока , поэтому вы не можете записать этот указатель.