任何人都可以解释一下记忆的布局
std::vector<std::array<int, 5>> vec(2)
Run Code Online (Sandbox Code Playgroud)
它是否提供具有2行5个元素的2D数组的连续内存块?
据我所知,矢量矢量
std::vector<std::vector<int>> vec(2, std::vector<int>(5))
Run Code Online (Sandbox Code Playgroud)
提供存储器中不同位置的两个 长度为 5个元素的连续数组的存储器布局.
对于数组的向量是否相同?
鉴于此std::array< T, 0 >,为什么它不是空的?我的意思是"空",如:
std::is_empty< std::array< int, 0 > >::value
Run Code Online (Sandbox Code Playgroud)
回来false和
#include <iostream>
#include <tuple>
#include <array>
struct Empty {};
int main()
{
std::cout << sizeof(std::tuple<int>) << std::endl;
std::cout << sizeof(std::tuple<int,Empty>) << std::endl;
std::cout << sizeof(std::tuple<int,std::array<int,0>>) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
产量
4
4
8
Run Code Online (Sandbox Code Playgroud)
这意味着,std::array<int,0>没有应用空基础优化(EBO).
这对我来说似乎特别奇怪std::tuple<>(注意:没有模板参数)是空的,即std::is_empty<std::tuple<>>::value产量true.
问题:为什么这样,因为这个尺寸0已经是一个特例了std::array?这是标准的故意还是疏忽?
第一次提问者:)是否有可能在不破坏代码的情况下将全局c样式数组转换为std :: arrays?我正在开发一个项目,其中包括反编译旧游戏的源代码.我们已经设法重构了反汇编/反编译输出的大部分内容.因为它是自动的,所以仍然有像
int a;
int b[50];
*(&a + 100) = xxx;
Run Code Online (Sandbox Code Playgroud)
要么
int b[50];
int a;
*(&a - 100) = xxx;
Run Code Online (Sandbox Code Playgroud)
还有其他类型的疯狂指针算术,它们尚未手动重构.但我们想使用边界检查已经(可能)正确更改为数组的部分.
(忽略斜体文本,我只是为了保持评论的一致性)到目前为止,我发现每个数组都有一个问题:sizeof(class containing array)会改变.这可能会在某些周期中破坏代码,例如someclass somearray [100]; //例如(sizeof(somearray [0])== 50)是真的int指针=(int)somearray; 指针+ = 100((someclass)指针) - > doSomething(); .因为pointer +=100不是指向第二个元素,而是指向第一个元素,或者甚至是第0个元素,我不确定(不要忘记它是自动反编译的代码,因此是丑陋的).
我正在考虑将每个全局数组更改为std :: array以及在没有[]运算符的情况下访问数组的每个实例array._Elems.
如果我要在这样的代码中将全局数组更改为std :: arrays,是否会出现任何问题?
编辑 你是对的,大小不变.我在测试功能中出错了.所以我会扩展这个问题:
将每个c样式数组更改为std :: array是否安全?
编辑 我们当前的代码实际上只能在调试模式下运行,因为它不会移动变量.发布模式基本上在程序开始时崩溃.
编辑 因为这个问题似乎有些混乱,让我澄清一下:除了T elems [N]之外,是否有一些保证阵列中没有其他成员?我能指望拥有
array<array<int,10>, 10> varname;
int* ptr = &varname[0][0];
ptr += 10
Run Code Online (Sandbox Code Playgroud)
varname[1][0] …
vector <int> V[]和vector< vector<int> > V两者都是2D阵列.
但是他们和我们在不同的地方使用它的区别是什么?请简要说明一下.
假设我们有一个指针,T* ptr;并且ptr, ptr+1, … ptr+(n-1)所有引用类型为T的有效对象.
是否有可能像STL一样访问它们array?或者执行以下代码:
std::array<T,n>* ay = (std::array<T,n>*) ptr
Run Code Online (Sandbox Code Playgroud)
调用未定义的行为?
既然std::array不允许更改其分配器,是否有办法确保指向数据地址的指针是对齐的?
例如,在GNU g ++ 4.8.4和6.1.0中,代码如下
#include <array>
#include <iostream>
int main(void)
{
std::array<bool, 10> a;
std::array<char, 10> b;
std::array<int,10> c;
std::array<long long, 10> d;
std::array<float, 10> e;
std::array<double, 10> f;
std::cout << "array<bool,10>.data() = " << a.data() << std::endl;
std::cout << "array<char,10>.data() = " << (void*) b.data() << std::endl;
std::cout << "array<int,10>.data() = " << c.data() << std::endl;
std::cout << "array<long long, 10>.data() = " << d.data() << std::endl;
std::cout << "array<float, 10>.data() = " << e.data() << …Run Code Online (Sandbox Code Playgroud) 我有以下类型:
std::vector<std::vector<int>> indicies
Run Code Online (Sandbox Code Playgroud)
其中内部向量的大小始终为2.问题是,向量在内存中是非连续的.我想用连续的东西替换内部向量,以便我可以抛出扁平数组:
int *array_a = (int *) &(a[0][0])
Run Code Online (Sandbox Code Playgroud)
如果新类型有[]运算符会很好,所以我不必更改整个代码.(如果有必要,我也可以自己实施).我的想法是:
std::vector<std::array<int, 2>>
Run Code Online (Sandbox Code Playgroud)
要么
std::vector<std::pair<int, int>>
Run Code Online (Sandbox Code Playgroud)
这些在内存中看起来如何?我写了一个小测试:
#include <iostream>
#include <array>
#include <vector>
int main(int argc, char *argv[])
{
using namespace std;
vector<array<int, 2>> a(100);
cout << sizeof(array<int, 2>) << endl;
for(auto i = 0; i < 10; i++){
for(auto j = 0; j < 2; j++){
cout << "a[" << i << "][" << j << "] "
<<&(a[i][j]) << endl;
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这导致:
8
a[0][0] …Run Code Online (Sandbox Code Playgroud) 给定二维数组
std::array<std::array<int, 2>, 3> m = {{ {1, 2}, {3, 4}, {5, 6} }};
Run Code Online (Sandbox Code Playgroud)
我正在寻找所有元素的总和 - 在这种情况下,21.如果数组是一维的,我可以写
auto sum = std::accumulate(m.begin(), m.end(), 0);
Run Code Online (Sandbox Code Playgroud)
但对于我的二维数组,这失败了,这是一个可以理解的错误
no match for 'operator+' (operand types are 'int' and 'std::array<int, 2ul>')
Run Code Online (Sandbox Code Playgroud)
我怎样才能优雅地为我的2D数组计算这个总和(避免for循环,更喜欢STL算法)?
是否可以像一维情况一样使用单线,或者它变得更复杂?
似乎,我发现如何在2行代码中轻松获得具有连续内存的普通2D数组:
template<int N, int M>
using Array2D = array<array<int, M>, N>;
Run Code Online (Sandbox Code Playgroud)
让我们来解决简单的任务交换最大和最小的Array2D(有点C++ 17):
template<int N, int M>
void printArray2D(const Array2D<N, M> &arr);
int main() {
const int N = 5;
const int M = 5;
Array2D<N, M> arr;
// random init of Array2D
generate(arr.front().begin(), arr.back().end(), []()->int {
return rand() % 100;
});
printArray2D(arr);
auto[a, b] = minmax_element(arr.front().begin(), arr.back().end());
cout << "Swap minimum and maximum: " << *a << " " << *b << endl << endl; …Run Code Online (Sandbox Code Playgroud) C++标准对sizeof(std::array<char, N>)应该是什么(对于某些常量N)说了些什么?
在对不同问题的评论中,提到std::array并不总是"堆栈分配".该评论是对一个不同的评论的回应,该评论推测将过大的常量std::array声明为局部变量可能导致程序因"资源分配"变量的资源不足而中止.我假设后续评论意味着有可能std::array以某种方式切换到动态分配模式.
我可以想象,可能会有某种SFINAE应用于数组大小阈值,触发std::array实际动态分配数组并对其进行管理的特化.在这种情况下,sizeof(std::array<...>)可能只是指针的大小.这是允许发生的吗?
它有保证sizeof (std::array<T, N>) == N * sizeof (T)吗?
请提供C++标准的支持.
还有一个相关的问题有关std::tr1::array.
为了帮助您入门:
std::array是一个聚合.如果T是POD,那也是std::array<T, N>.这使它也成为标准布局.
应该有一些标准参考连接到禁止填充(允许对齐填充,但数组长度已经是其对齐的倍数).
看起来这个代码工作(所以它编译得很好),我在这里问的是:它是否保证sizeof(std :: array)与sizeof(equivalent_Carray)相同?
struct MyClass {
std::array<float, 4> arr;
float carr[4];
std::array<float, 4> cfunction() {
std::array<float, sizeof(carr) / sizeof(float)> out;
return out;
}
std::array<float, 4> function() {
// Is this guaranteed to be the same as sizeof(carr) / sizeof(float)??
std::array<float, sizeof(arr) / sizeof(float)> out;
std::cout << sizeof(arr);
return out;
}
};
int main()
{
MyClass obj;
obj.function();
}
Run Code Online (Sandbox Code Playgroud) 作为使用 React Native 的移动开发人员,我需要使用创建和加密文件的 C++ 代码。我对 C++ 没有太多经验(我上次写一些东西已经是 15 年前在大学时的事了)。
如果我错了,请纠正我。
这让我很烦恼。这是文件的类型定义:
typedef struct File
{
uint8_t FileName[64];
uint8_t userName[64];
}File;
Run Code Online (Sandbox Code Playgroud)
为什么要使用类型uint8_t来存储字符串而不是std::string?
后来,事情变得更加扑朔迷离。我们需要将所有字符一一解析出来,并写入到临时文件中。
#define FILE_NAME_LEN 64
CustomFile CFile::getCustomFileFromFile(tFile f_File)
{
CustomFile returnValue;
for(int i = 0;i<FILE_NAME_LEN;i++){
returnValue.FileName[i] = f_File.FileName[i];
}
for(int i = 0;i<FILE_NAME_LEN;i++){
returnValue.user_name[i] = f_File.user_name[i];
}
return returnValue;
}
bool WriteEncryptFile(QString fpath,tFile *p_tFile)
{
// Convert the tFile object to a CustomFile object
CustomFile customFile = CFile::getCustomFileFromFile(*p_tFile);
}
Run Code Online (Sandbox Code Playgroud) c++ ×13
c++11 ×9
arrays ×7
stdarray ×3
c++14 ×2
sizeof ×2
vector ×2
allocation ×1
containers ×1
disassembly ×1
matrix ×1
memory ×1
std ×1
stdvector ×1
stl ×1
type-punning ×1
uint8t ×1