2016-09-22 16 views
0

Я пытаюсь прочитать аргумент командной строки в массив unsigned char с фиксированным размером. Я получаю ошибку сегментации.C++ чтение argv в unsigned char фиксированный размер: ошибка сегментации

Мой код:

#include <stdio.h> 
#include <iostream> 
#include <stdlib.h> 
#include <memory.h> 

unsigned char key[16]={}; 

int main(int argc, char** argv){ 
     std::cout << "Hello!" << std::endl; 
     long a = atol(argv[1]); 
     std::cout << a << std::endl; 
     memcpy(key, (unsigned char*) a, sizeof key); 
//  std::cout << sizeof key << std::endl; 
//  for (int i = 0; i < 16; i++) 
//    std::cout << (int) (key[i]) << std::endl; 
     return 0; 
} 

Что я делаю неправильно?

Для вызова программы:

компиляции: g++ main.cpp

Execute: ./a.out 128

+0

Ваш вопрос не заполнен. Как вы называете свою программу? –

+0

Что вы перешли на главную ???? – Raindrop7

+0

Может быть любое число от 0 до 2^128, верно? !! – algoProg

ответ

2

Вы получаете SEGV потому, что ваш адрес является неправильным: вы преобразовать значение адреса. Плюс размер является одним из назначения, должен быть размер источника

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

xxx.c:12:38: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 

    memcpy(key, (unsigned char*) a, sizeof key); 
           ^

фикс, что нравится:

memcpy(key, &a, sizeof(a)); 

BTW вы не должны объявить key с 16 байт. Было бы безопаснее передать его так:

unsigned char key[sizeof(long)]; 

и при печати байт, не перебирать до sizeof(long) также, или вы просто печатать мусорные байты в конце концов.

Вот предложение исправить с помощью uint64_t (беззнакового 64-разрядного целого числа от stdint.h, который дает точный контроль над размером), ноль инициализация для key и анализ с помощью strtoll:

#include <stdio.h> 
#include <iostream> 
#include <stdlib.h> 
#include <memory.h> 
#include <stdint.h> 

unsigned char key[sizeof(uint64_t)]={0}; 

int main(int argc, char** argv){ 
     std::cout << "Hello!" << std::endl; 
     uint64_t a = strtoll(argv[1],NULL,10); 
     memcpy(key, &a, sizeof a); 

     for (int i = 0; i < sizeof(key); i++) 
       std::cout << (int) (key[i]) << std::endl; 
     return 0; 
} 

(если вы хотите обрабатывать подписаны, просто изменить к int64_t)

Тест на маленькой архитектуры Endian:

% a 10000000000000 
Hello! 
0 
160 
114 
78 
24 
9 
0 
0 
+0

Привет, Жан, это моя проблема. Должен ли я сделать это долго? – algoProg

+0

@ 1201ProgramAlarm: не совсем, вы были правы, спасибо. Мне не хватало конверсии из целого числа в адрес! –

+0

Это исправлено. Больше не виноват. Как я могу проверить, какое значение сейчас в ключе? Мой прокомментированный цикл печати не работает. Компилятор печатает '?'. – algoProg

0

Похоже, вы копируете слишком много данных. Я также добавил & a для memcpy.

#include <stdio.h> 
#include <iostream> 
#include <stdlib.h> 
#include <memory.h> 

unsigned char key[16]={}; 

int main(int argc, char** argv) 
{ 
    memset(key,0x0, sizeof(key)); 
    std::cout << "Hello!" << std::endl; 
    long a = atol(argv[1]); 
    std::cout << a << std::endl; 

    // the size parameter needs to be the size of a 
    // or the lesser of the size of key and a 
    memcpy(key,(void *) &a, sizeof(a)); 
    std::cout << "size of key " << sizeof(key) << "\n"; 
    std::cout << "key " << key << "\n"; 
    for (int i = 0; i < 16; i++) 
    std::cout << " " << i << " '" << ((int) key[i]) << "'\n"; 
    return 0; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^