小编Ins*_*oop的帖子

Google如何处理C++中的错误

Google不会在其C++代码库中使用异常.对于错误,它们使用一个名为status的类,而不是程序员从函数返回时必须检查的类.否则程序无法编译(在41:34 链接https://www.youtube.com/watch?v=NOCElcMcFik).我有几个问题:

1)网上是否有免费提供该课程的例子?

2)对于"void f()",可以使用可以转换成"状态f()"的副作用.但是如果你的函数已经返回一个值怎么办?Google不允许传递非const的引用,因此您无法改变提供给您的Status对象.那他们怎么办?

谢谢你的帮助.

c++ exception

7
推荐指数
1
解决办法
317
查看次数

如何查找是否有内存泄漏

我写了一个数字运算算法.这个想法是:

  1. 一个小的主程序需要很少的内存(从2 MB开始)
  2. 然后,在循环中,它调用一个需要相当大的内存(大约100 MB)的函数,该函数应在函数结束时释放.为了理解发生了什么,现在总是使用相同的参数调用该函数.

似乎程序慢慢占用内存所以我怀疑内存泄漏.我曾尝试过来自英特尔的Clang和Pointer Checker的Address Sanitizer,但他们没有找到任何东西.

现在,我正在调查我的Activity Monitor中的内存消耗(我正在运行OSX,但是我从Unix命令"top"获得了相同的内存使用情况)并且在调用big函数之前,该程序需要2 MB.运行该功能时,程序需要120 MB.奇怪的是,当程序结束大功能并返回循环内部时,它现在需要37 MB!然后,当它返回到大功能时,它需要130 MB.再次回到循环中,需要36 MB,然后在大功能中需要140 MB ...

所以它正在逐渐消失,但不是常规模式.我应该如何信任"top"中的内存使用情况?

内存碎片可以增加内存使用而不会出现内存泄漏吗?


我让程序一夜之间运行,这是我得到的数据:

  1. 在第一个循环中,程序需要150 MB
  2. 2小时后,在68次循环后,程序需要220 MB
  3. 一晚和394循环后,该程序需要480 MB

因此,似乎分配和释放内存(大约120 MB)的函数似乎每次调用时"泄漏"1 MB.

c++ memory-leaks

7
推荐指数
1
解决办法
472
查看次数

C++动态数组的设计

我正在为动态数组设计一些类(类似于std :: vector).我不想使用std :: vector的原因是因为我的C++程序经常被用作从C/C++/Fortran/Delphi调用的库,因此将数组输入作为指针.出于安全原因,std :: vector在构造时不能窃取指针.我的Array1D可以作为std :: vector工作,但也可以用指针构造.不幸的是,Visual Studio 2013似乎担心我的设计.在提出问题之前,我需要解释一下这个设计.

这是我班级的布局

template <typename T>
class Array1D {
private:
    T* data_;
    T* size_;    // No stored as an int for optimisation purposes
    bool owner_;
public:
    Array1D(int n) {
        data_ = new T[n];
        size_ = data_ + n;
        owner_ = true;
    }
    Array1D(T* data, int n) {
        data_ = data;
        size_ = data + n;
        owner_ = false;
    }
    ...
};
Run Code Online (Sandbox Code Playgroud)

大多数情况下,它作为std :: vector工作,owner_设置为true.也可以从指针构造一个Array1D,这次owner_设置为false.在这种情况下,不允许某些操作(例如调整大小)(通过断言).复制构造函数和数组A的赋值设计为:

  • Array1D(const Array1D&B):B的深层拷贝到A.构造之后,A拥有它的内存.
  • Array1D(Array1D && B):在所有情况下移动操作.施工后,A的所有权状态与B相同.
  • operator =(const …

arrays c++11

6
推荐指数
1
解决办法
245
查看次数

尽管错误共享,速度仍会提高

我一直在对OpenMP进行一些测试,并且由于错误共享数组"sum"而使得该程序不应该扩展.我遇到的问题是它确实可以扩展.更糟":

  • 1个线程:4秒(icpc),4秒(g ++)
  • 2线程:2秒(icpc),2秒(g ++)
  • 4线程:0.5秒(icpc),1秒(g ++)

我真的没有通过英特尔编译器获得从2个线程到4个线程的加速.但最重要的是:为什么扩展如此好,即使它应该表现出错误的共享?

#include <iostream>
#include <chrono>

#include <array>

#include <omp.h>

int main(int argc, const char *argv[])
{
    const auto nb_threads = std::size_t{4};
    omp_set_num_threads(nb_threads);

    const auto num_steps = std::size_t{1000000000};
    const auto step = double{1.0 / num_steps};
    auto sum = std::array<double, nb_threads>{0.0};
    std::size_t actual_nb_threads;

    auto start_time = std::chrono::high_resolution_clock::now();
    #pragma omp parallel
    {
        const auto id = std::size_t{omp_get_thread_num()};
        if (id == 0) {
            // This is needed because OMP might give us less threads
            // than the …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading openmp false-sharing

6
推荐指数
1
解决办法
235
查看次数

C++标准强加的整数范围

这个问题是关于C++标准对基本整数类型的范围的影响.在C++ 17标准中,6.9.1关于基本类型的观点有一个点4,它表示:

无符号整数应遵守算术模数的定律,2^n 其中n是该特定整数大小的值表示中的位数.

在C标准中,它只表示if [0, max]是可以用无符号整数表示的范围,超出此范围的所有操作都以模数减少range + 1.它永远不会说range + 1应该是2的力量.

这个C++标准的引用是否意味着所有无符号整数都有这样的范围[0, 2^n - 1]?我们可以从那一点推断出所有有符号整数都有一个范围的形式[-2^(n/2), 2^(n/2) - 1]吗?

我在标准中没有看到任何说法,但之前引用的标准似乎暗示了那种事情.


PS:这个问题与此处给出的副本不同.关联的问题是为什么标准中没有强制执行两个补码.我的问题是关于实际标准中的内容.

c++

6
推荐指数
1
解决办法
173
查看次数

检查传递给函数的数组的大小

我在一个子程序编写为的大型程序中发现了一个错误:

program main
  implicit none

  real, dimension(6) :: x
  call f(x, 7)
  write (*,*) x
contains
  subroutine f(x, n)
    integer :: n
    real, dimension(n) :: x

    integer :: i

    do i = 1, n
      x(i) = 0.0
    end do
  end subroutine f
end program main
Run Code Online (Sandbox Code Playgroud)

即使代码显然存在错误,该程序也可以与ifort和gfortran一起运行并进行边界检查。是否可以捕获此类错误?

PS:这是生成可以正常运行的二进制文件的两个命令

  • ifort -check all main.f90 -o main
  • gfortran -fbounds-check main.f90 -o main

fortran

6
推荐指数
1
解决办法
175
查看次数

数组索引的类型:有符号/无符号整数优点

在C ++中,数组索引的默认大小为size_t,这是大多数x86-64平台上的64位无符号 64位整数。我正在为自己的高性能计算库构建自己的std :: vector类(主要原因之一是我希望该类能够获得指针的所有权,而std :: vector却没有提供)。对于数组索引的类型,我正在考虑使用以下任一方法:

  • size_t
  • 我自己的index_t将是一个有符号的 int或一个长的有符号的int,具体取决于我的程序

与无符号整数相比,使用有符号整数的优势很多,例如

for (index_t i = 0; i < v.size() - 1; ++i)
Run Code Online (Sandbox Code Playgroud)

的工作方式就像是假设的(使用无符号整数,当v的大小为0时,此循环会变得疯狂)

for (index_t i = v.size() - 1; i >= 0; --i)
Run Code Online (Sandbox Code Playgroud)

像预期的那样工作,还有许多其他优点。在性能方面,它甚至看起来要好一些

a + 1 < b + 1
Run Code Online (Sandbox Code Playgroud)

可以减少为带符号整数的<b(未定义溢出),而对于无符号整数则不能。唯一有利的性能明智的做法是,可以将/ = 2简化为使用无符号整数的移位操作,而不是使用有符号整数的移位操作。

我想知道为什么C ++委员会决定对size_t 使用无符号整数,因为这似乎带来了很多麻烦,并且只有很少的优点。

c c++

5
推荐指数
2
解决办法
3554
查看次数

返回值优化是否需要声明复制构造函数

我发现英特尔编译器不会为std :: array对象生成返回值优化.以下代码恰好位于我的程序的内部循环中,并未进行优化.

std::array<double, 45> f(const std::array<double, 45>& y) {
    auto dy_dt = std::array<double, 45>( );
    ...

    return dy_dt;
}
Run Code Online (Sandbox Code Playgroud)

我已经发现这种行为来自于我的标准库实现没有为std :: array显式定义复制构造函数的事实.以下代码演示了:

class Test {
public:
    Test() = default;
    Test(const Test& x);
};

Test f() {
    auto x = Test( );

    return x;
}
Run Code Online (Sandbox Code Playgroud)

用它编译时

icpc -c -std=c++11 -qopt-report=2 test.cpp -o test.o
Run Code Online (Sandbox Code Playgroud)

报告文件显示

INLINE REPORT: (f(Test *)) [1] main.cpp(7,10)
Run Code Online (Sandbox Code Playgroud)

这证明了编译器生成了RVO(f的签名被更改,因此它可以将新创建​​的对象放在调用站点的堆栈上).但是,如果您注释掉声明的行Test(const Test& x);,则报告文件会显示

INLINE REPORT: (f()) [1] main.cpp(7,10)
Run Code Online (Sandbox Code Playgroud)

这证明RVO没有生成.

在定义RVO的C++ 11标准的12.8.31中,他们给出的示例有一个复制构造函数.那么,这是英特尔编译器的"错误"还是符合标准的实现?

c++ rvo

5
推荐指数
1
解决办法
278
查看次数

记忆消毒剂

我在Ubuntu 14.04上使用Clang 3.7.0玩Memory Sanitizer.以下代码可以完美地运行:

#include <cstdio>

int main() {
  double ans;
  printf("Hello World: %f\n", ans);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译时

 clang++ -g -O1 -fsanitize=memory -fsanitize-memory-track-origins=2 -fomit-frame-pointer sanitize.cpp -o sanitize
Run Code Online (Sandbox Code Playgroud)

我期待一个错误.Memory Sanitizer没有捕获ans未初始化的事实吗?

谢谢你的帮助.

c++ sanitizer msan

5
推荐指数
1
解决办法
1311
查看次数

从Cython代码生成SIMD指令

我需要概述一下在高性能数字代码中使用Cython可以获得的性能.我感兴趣的一件事是找出优化的C编译器是否可以对Cython生成的代码进行矢量化.所以我决定编写以下小例子:

import numpy as np
cimport numpy as np
cimport cython

@cython.boundscheck(False)
@cython.wraparound(False)
cpdef int f(np.ndarray[int, ndim = 1] f):
    cdef int array_length =  f.shape[0]
    cdef int sum = 0
    cdef int k
    for k in range(array_length):
        sum += f[k]
    return sum
Run Code Online (Sandbox Code Playgroud)

我知道有Numpy函数可以完成这项工作,但我希望有一个简单的代码,以便了解Cython的可能性.事实证明,生成的代码:

from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules = cythonize("sum.pyx"))
Run Code Online (Sandbox Code Playgroud)

并呼吁:

python setup.py build_ext --inplace
Run Code Online (Sandbox Code Playgroud)

为循环生成一个看起来像这样的C代码:

for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2 += 1) {
  __pyx_v_sum = __pyx_v_sum + (*(int *)((char *) 
    __pyx_pybuffernd_f.rcbuffer->pybuffer.buf + …
Run Code Online (Sandbox Code Playgroud)

python cython

5
推荐指数
1
解决办法
913
查看次数