Nee*_*hta 1 string qt pointers memcpy character-arrays
我有一个代码,其中字符数组由整数填充(转换为char数组),并由另一个函数读取,该函数将其重新转换回整数.我使用以下函数来转换为char数组:
char data[64];
int a = 10;
std::string str = boost::lexical_cast<std::string>(a);
memcpy(data + 8*k,str.c_str(),sizeof(str.c_str())); //k varies from 0 to 7
Run Code Online (Sandbox Code Playgroud)
并使用以下方法重新转换回字符:
char temp[8];
memcpy(temp,data+8*k,8);
int a = atoi(temp);
Run Code Online (Sandbox Code Playgroud)
这一般工作正常,但是当我尝试将其作为涉及qt(ver 4.7)的项目的一部分时,它编译得很好并且在尝试使用memcpy()读取时给出了分段错误.请注意,分段故障仅在读取循环中发生,而不是在写入数据时发生.我不知道为什么会这样,但我希望通过任何方法完成它.
那么,还有其他任何我可以使用的函数可以接受字符数组,第一位和最后一位并将其转换为整数.然后我根本不必使用memcpy().我想要做的是这样的事情:
new_atoi(data,8*k,8*(k+1)); // k varies from 0 to 7
Run Code Online (Sandbox Code Playgroud)
提前致谢.
您只复制4个字符(取决于系统的指针宽度).这将使4+个字符的数字非空终止,导致atoi输入中的失控字符串
sizeof(str.c_str()) //i.e. sizeof(char*) = 4 (32 bit systems)
Run Code Online (Sandbox Code Playgroud)
应该
str.length() + 1
Run Code Online (Sandbox Code Playgroud)
或者字符不会被终止
make_testdata():一路看下来
你为什么不用流......?
#include <sstream>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
int main()
{
std::vector<int> data = make_testdata();
std::ostringstream oss;
std::copy(data.begin(), data.end(), std::ostream_iterator<int>(oss, "\t"));
std::stringstream iss(oss.str());
std::vector<int> clone;
std::copy(std::istream_iterator<int>(iss), std::istream_iterator<int>(),
std::back_inserter(clone));
//verify that clone now contains the original random data:
//bool ok = std::equal(data.begin(), data.end(), clone.begin());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你可以使用atoi/itoa和一些调整在普通的C中做得更快,但我认为如果你需要速度,你应该使用二进制传输(参见Boost Spirit Karma和protobuf用于好的库).
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
namespace qi=::boost::spirit::qi;
namespace karma=::boost::spirit::karma;
static const char delimiter = '\0';
int main()
{
std::vector<int> data = make_testdata();
std::string astext;
// astext.reserve(3 * sizeof(data[0]) * data.size()); // heuristic pre-alloc
std::back_insert_iterator<std::string> out(astext);
{
using namespace karma;
generate(out, delimit(delimiter) [ *int_ ], data);
// generate_delimited(out, *int_, delimiter, data); // equivalent
// generate(out, int_ % delimiter, data); // somehow much slower!
}
std::string::const_iterator begin(astext.begin()), end(astext.end());
std::vector<int> clone;
qi::parse(begin, end, qi::int_ % delimiter, clone);
//verify that clone now contains the original random data:
//bool ok = std::equal(data.begin(), data.end(), clone.begin());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果您想要进行独立于体系结构的二进制序列化,那么您将使用这种微小的适应性使事情变得快几十倍(参见下面的基准测试......):
karma::generate(out, *karma::big_dword, data);
// ...
qi::parse(begin, end, *qi::big_dword, clone);
Run Code Online (Sandbox Code Playgroud)
在二进制模式下使用Boost Serialization时,可以达到最佳性能:
#include <sstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/vector.hpp>
int main()
{
std::vector<int> data = make_testdata();
std::stringstream ss;
{
boost::archive::binary_oarchive oa(ss);
oa << data;
}
std::vector<int> clone;
{
boost::archive::binary_iarchive ia(ss);
ia >> clone;
}
//verify that clone now contains the original random data:
//bool ok = std::equal(data.begin(), data.end(), clone.begin());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
(以上所有版本通用)
#include <boost/random.hpp>
// generates a deterministic pseudo-random vector of 32Mio ints
std::vector<int> make_testdata()
{
std::vector<int> testdata;
testdata.resize(2 << 24);
std::generate(testdata.begin(), testdata.end(), boost::mt19937(0));
return testdata;
}
Run Code Online (Sandbox Code Playgroud)
我对它进行了基准测试
2<<24(33554432)随机整数的输入数据generate_delimited:)| 归档时间: |
|
| 查看次数: |
1586 次 |
| 最近记录: |