[英]c++ reading argv into unsigned char fixed size: Segmentation fault
I am trying to read command line argument into a fixed size unsigned char array. 我正在尝试将命令行参数读入固定大小的无符号字符数组。 I get segmentation fault.
我遇到细分错误。
My code: 我的代码:
#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;
}
What am I doing wrong? 我究竟做错了什么?
To call the program: 调用程序:
compile: g++ main.cpp
编译:
g++ main.cpp
Execute: ./a.out 128
执行:
./a.out 128
You get SEGV because your address is wrong: you convert a value to an address. 您收到SEGV是因为您的地址错误:将值转换为地址。 Plus the size is the one of the destination, should be the size of the source
加大小是目的地之一,应该是来源的大小
The compiler issues a warning, that's never good, you should take it into account because that was exactly your error: 编译器发出警告,那永远不会好,您应该考虑它,因为那恰恰是您的错误:
xxx.c:12:38: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
memcpy(key, (unsigned char*) a, sizeof key);
^
fix that like this: 像这样解决:
memcpy(key, &a, sizeof(a));
BTW you don't have to declare key
with 16 bytes. 顺便说一句,您不必声明16个字节的
key
。 It would be safer to allocate it like this: 这样分配它会更安全:
unsigned char key[sizeof(long)];
and when you print the bytes, iterate until sizeof(long)
too, or you'll just print trash bytes in the end. 当您打印字节时,也要迭代到
sizeof(long)
,否则最后只打印垃圾字节。
Here's a fix proposal using uint64_t
(unsigned 64-bit integer from stdint.h
which gives exact control on the size), zero initialization for your key
and parsing using strtoll
: 这是一个使用
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;
}
(if you want to handle signed, just change to int64_t
) (如果要处理签名,只需更改为
int64_t
)
Test on a little endian architecture: 在小端架构上测试:
% a 10000000000000
Hello!
0
160
114
78
24
9
0
0
Looks like you are copying too much data. 看来您正在复制太多数据。 I also added a &a for the memcpy.
我还为memcpy添加了&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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.