mjn*_*n12 35 c++ arrays pointers copy
我有一个foo(int[] nums)我理解的功能基本上相当于foo(int* nums).在里面foo我需要将指向的数组的内容复制nums到一些int[10]声明的范围内foo.我理解以下内容无效:
void foo (int[] nums)
{
myGlobalArray = *nums
}
Run Code Online (Sandbox Code Playgroud)
复制数组的正确方法是什么?我应该像这样使用memcpy:
void foo (int[] nums)
{
memcpy(&myGlobalArray, nums, 10);
}
Run Code Online (Sandbox Code Playgroud)
或者我应该使用for循环?
void foo(int[] nums)
{
for(int i =0; i < 10; i++)
{
myGlobalArray[i] = nums[i];
}
}
Run Code Online (Sandbox Code Playgroud)
我缺少第三种选择吗?
Oli*_*rth 62
是的,第三个选项是使用C++构造:
std::copy(&nums[0], &nums[10], myGlobalArray);
Run Code Online (Sandbox Code Playgroud)
使用任何理智的编译器,它:
memcpy()尽可能编译),Jay*_*Jay 22
Memcpy可能会更快,但你更有可能在使用它时犯了错误.它可能取决于优化编译器的智能程度.
但是你的代码不正确.它应该是:
memcpy(&myGlobalArray, nums, 10 * sizeof(int) );
Run Code Online (Sandbox Code Playgroud)
一般来说,最糟糕的情况是在未优化的调试版本中,其中memcpy没有内联,并且可能执行额外的健全性/断言检查,相当于少量额外指令与for循环.
然而memcpy,通常很好地实现了利用内在函数等内容,但这将随目标体系结构和编译器而变化.它不太可能memcpy比for循环实现更糟糕.
人们常常嘲笑memcpy以字节为单位的事实,他们写下这样的事情:
// wrong unless we're copying bytes.
memcpy(myGlobalArray, nums, numNums);
// wrong if an int isn't 4 bytes or the type of nums changed.
memcpy(myGlobalArray, nums, numNums);
// wrong if nums is no-longer an int array.
memcpy(myGlobalArray, nums, numNums * sizeof(int));
Run Code Online (Sandbox Code Playgroud)
您可以通过使用可以进行某种程度反思的语言功能来保护自己,即:根据数据本身而不是您对数据的了解来做事情,因为在通用函数中,您通常不知道任何事情关于数据:
void foo (int* nums, size_t numNums)
{
memcpy(myGlobalArray, nums, numNums * sizeof(*nums));
}
Run Code Online (Sandbox Code Playgroud)
请注意,您不希望"&global"面向"myGlobalArray",因为数组会自动衰减为指针; 你实际上是将"nums"复制到内存中指向myGlobalArray [0]的指针的地址.
(编辑注释:int[] nums当我的意思是,我错了,int nums[]但我决定添加C数组 - 指针 - 等效混乱帮助没人,所以现在它是int *nums:))
memcpy在对象上使用可能很危险,请考虑:
struct Foo {
std::string m_string;
std::vector<int> m_vec;
};
Foo f1;
Foo f2;
f2.m_string = "hello";
f2.m_vec.push_back(42);
memcpy(&f1, &f2, sizeof(f2));
Run Code Online (Sandbox Code Playgroud)
这是复制非POD(普通旧数据)对象的错误方法.f1和f2现在都有一个std :: string,认为它拥有"hello".其中一个在破坏时会崩溃,他们都认为他们拥有包含42的整数相同的向量.
C++程序员的最佳实践是使用std::copy:
std::copy(nums, nums + numNums, myGlobalArray);
Run Code Online (Sandbox Code Playgroud)
请注意每个Remy Lebeau或自C++ 11以来
std::copy_n(nums, numNums, myGlobalArray);
Run Code Online (Sandbox Code Playgroud)
这可以使编译时决定做什么,包括使用memcpy或memmove可能使用SSE /向量指令.另一个优点是,如果你这样写:
struct Foo {
int m_i;
};
Foo f1[10], f2[10];
memcpy(&f1, &f2, sizeof(f1));
Run Code Online (Sandbox Code Playgroud)
然后改变Foo包含一个std::string,你的代码就会破解.如果你改为写:
struct Foo {
int m_i;
};
enum { NumFoos = 10 };
Foo f1[NumFoos], f2[NumFoos];
std::copy(f2, f2 + numFoos, f1);
Run Code Online (Sandbox Code Playgroud)
编译器将切换您的代码以做正确的事情而无需任何额外的工作,并且您的代码更具可读性.
| 归档时间: |
|
| 查看次数: |
53204 次 |
| 最近记录: |