c ++将argv读入unsigned char固定大小:分段错误

时间:2016-09-22 19:46:14

标签: c++ segmentation-fault argv unsigned-char

我正在尝试将命令行参数读入固定大小的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;
}

我做错了什么?

致电该计划:

编译:{{1​​}}

执行:g++ main.cpp

2 个答案:

答案 0 :(得分: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));

顺便说一句,您不必使用16个字节声明key。像这样分配它会更安全:

unsigned char key[sizeof(long)];

当你打印字节时,迭代到sizeof(long),或者你最后只打印垃圾字节。

以下是使用uint64_t的修正提案(来自stdint.h的无符号64位整数,可以精确控制大小),key初始化为零,使用{{1}进行解析}:

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

答案 1 :(得分:0)

看起来你正在复制太多数据。 我还为memcpy添加了一个&amp; a。

#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;
}