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

c++ reading argv into unsigned char fixed size: Segmentation fault

本文关键字:错误 分段 char argv 读取 unsigned c++      更新时间:2023-10-16

我试图将命令行参数读取为固定大小的无符号字符数组。我得到分割错误。

我代码:

#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

你得到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的零初始化和使用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;
}

(如果你想处理signed,只需更改为int64_t)

在小端序架构上测试:

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

看起来你复制了太多的数据。我还为内存添加了&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;
}