std :: copy导致错误无异常

时间:2015-08-24 07:52:02

标签: c++ embedded-linux

我有这个代码来复制一个整数:

int parseInt(const char* data, unsigned int* ind) {
    int i;

    std::copy(&data[*ind], &data[*ind+sizeof(int)], &i); // i) STD::COPY
    // memcpy(&i, &data[*ind], sizeof(int)); // ii) MEMCPY
    std::cout << "--> " << i << std::endl;
    *ind += sizeof(int);
    std::cout << "OK" << std::endl;
    return i;
}

debian上,此代码有效 i)STD :: COPY

然后,我编译并运行嵌入式Arm 上的代码(sizeof(int)也是4)。带有 i)的代码似乎也在运行,在函数中打印预期。

但是,从函数返回时会导致问题。

我也尝试了return 1;而不是i,但也是如此。它没有抛出异常,也没有给出任何线索。我无法调试,因为我无法添加调试器,因为我有限制。

在此功能之后它才会继续,即:

std::cout << "PARSING..." << std::endl;
parseInt(data, &ind);
std::cout << "PARSED!" << std::endl;
...

给出这个(值11是正确的):

PARSING...
--> 11
OK

然后这个过程冻结了。

但是,当我使用 ii)MEMCPY 而不是std::copy时,代码可以正常工作。因此,由于std::copy,我似乎出现了这个问题。

有谁知道这里可以发生什么?

我是否错误地使用std::copy?但是为什么它可以在debian桌面上工作但不能在arm嵌入式上工作?

3 个答案:

答案 0 :(得分:8)

std::copy(&data[*ind], &data[*ind+sizeof(int)], &i);

这会将sizeof(int)个字节复制到从int开始的&i数组的连续元素,不用说这会导致未定义的行为,因为&i处没有数组。< / p>

你可能意味着

std::copy(&data[*ind], &data[*ind+sizeof(int)], reinterpret_cast<char*>(&i));

memcpy工作的原因是因为它显式地复制了字节,std::copy更通用,就像它在抽象迭代器上运行的其他标准算法一样,由您决定是否正确调用它。

答案 1 :(得分:1)

std :: copy的文档:

 template <class InputIterator, class OutputIterator>   OutputIterator  
    copy (InputIterator first, InputIterator last, OutputIterator result);  

Copy range of elements Copies the elements in the range [first,last)
into the range beginning at result.

您正在使用const char *类型的输入迭代器。输出迭代器的类型为int *。
复制函数从第一个到最后一个迭代,导致4次迭代。每次迭代每次在输入中前进一个字节。但输出迭代器的类型为int *,因此每次迭代输出迭代器前进4个字节。这导致您的4个输入字节被复制,每个字节间隔3个字节 由于接收该数据的元素是变量i,它只能容纳一个int(4个字节),因此会导致未定义的行为,这些行为表现在未指定的内存位置。很可能会覆盖RET指令返回到相应CALL所需的方向 在debian中不会发生这样的事情取决于编译器的内存模型。你不能相信它是一致的。

在使用std :: copy时解决它的一种方法是使用char * iterator作为输出迭代器:

char* ptrDest = reinterpret_cast<char*>(&i);
std::copy(&data[*ind], &data[*ind+sizeof(int)], ptrDest); // i) STD::COPY

答案 2 :(得分:-2)

您的ARM CPU可能不支持未对齐的内存访问。 memcpy会为你处理这种情况。