小编Pet*_*ter的帖子

以合理,安全和有效的方式复制文件

我搜索一个复制文件(二进制或文本)的好方法.我写过几个样本,每个人都在工作.但我想听听经验丰富的程序员的意见.

我错过了很好的例子并搜索了一种适用于C++的方法.

ANSI-C-WAY

#include <iostream>
#include <cstdio>    // fopen, fclose, fread, fwrite, BUFSIZ
#include <ctime>
using namespace std;

int main() {
    clock_t start, end;
    start = clock();

    // BUFSIZE default is 8192 bytes
    // BUFSIZE of 1 means one chareter at time
    // good values should fit to blocksize, like 1024 or 4096
    // higher values reduce number of system calls
    // size_t BUFFER_SIZE = 4096;

    char buf[BUFSIZ];
    size_t size;

    FILE* source = fopen("from.ogv", "rb");
    FILE* dest = fopen("to.ogv", "wb"); …
Run Code Online (Sandbox Code Playgroud)

c++ file-io

292
推荐指数
4
解决办法
18万
查看次数

对STL容器的安全并行只读访问

我想从并行运行的线程访问基于STL的容器只读.不使用任何用户实现的锁定.以下代码的基础是C++ 11,它具有适当的标准实现.

http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_concurrency.html
http://www.sgi.com/tech/stl/thread_safety.html
http://www.hpl.hp.com/personal/ Hans_Boehm/c ++ mm/threadsintro.html
http://www.open-std.org/jtc1/sc22/wg21/(当前草案N3337,基本上是C++ 11,有轻微错误和错别字)

23.2.2集装箱数据竞赛[container.requirements.dataraces]

为避免数据争用(17.6.5.9),实现应将以下函数视为const:begin,end,rbegin,rend,front,back,data,find,lower_bound,upper_bound,equal_range,at和,除了关联或无序的关联容器,operator [].

尽管如此(17.6.5.9),除了vector <bool>之外,同时修改了同一序列中不同元素中包含对象的内容时,需要实现以避免数据争用.

[注意:对于大小大于1的向量<int> x,x [1] = 5和*x.begin()= 10可以在没有数据争用的情况下同时执行,但是x [0] = 5和*并发执行的x.begin()= 10可能导致数据竞争.作为一般规则的例外,对于向量<bool> y,y [0] = true可以与y [1] = true竞争. - 结束说明]

17.6.5.9数据竞争规避[res.on.data.races] 1本节规定了实现为防止数据竞争而应满足的要求(1.10).除非另有说明,否则每个标准库函数均应满足各项要求 在下面指定的情况下,实现可能会阻止数据争用.

2 C++标准库函数不应直接或间接访问除当前线程以外的线程可访问的对象(1.10),除非通过函数的论证直接或间接访问对象,包括此参数.

3 C++标准库函数不应直接或间接修改除当前线程以外的线程可访问的对象(1.10),除非通过函数的非const参数直接或间接访问对象,包括此参数.

4 [注意:这意味着,例如,实现不能在没有同步的情况下将静态对象用于内部目的,因为即使在未在线程之间显式共享对象的程序中,它也可能导致数据竞争. - 结束说明]

5 C++标准库函数不应通过其参数或其容器参数的元素访问可间接访问的对象,除非通过调用其规范所需的函数来容纳这些容器元素.

6通过调用标准库容器或字符串成员函数获得的迭代器操作可以
访问底层容器,但不得修改它.[注意:特别是,使迭代器无效的容器操作与与该容器关联的迭代器上的操作冲突. - 结束说明]

7如果对象对用户不可见并且受到数据竞争保护,则实现可以在线程之间共享它们自己的内部对象.

8除非另有说明,否则C++标准库函数应仅在当前线程内执行所有操作(如果这些操作具有对用户可见(1.10)的效果).

9 [注意:如果没有可见的副作用,这允许实现并行化操作. - 结束说明]

结论
容器不是线程安全的!但是从多个并行线程调用容器上的const函数是安全的.因此,可以在没有锁定的情况下从并行线程执行只读操作.我对吗?

我假装它们不存在任何错误的实现,并且C++ 11标准的每个实现都是正确的.

样品:

// concurrent …
Run Code Online (Sandbox Code Playgroud)

c++ containers multithreading stl c++11

20
推荐指数
1
解决办法
3870
查看次数

使用前缀或后缀增量(或减量)

我发现这段代码是在C++书籍(C++ Primer,第5版)中使用逗号运算符的一个例子:

vector<int>::size_type cnt = ivec.size();
// assign values from size...1 to the elements in ivec
for(vector<int>::size_type ix = 0; ix != ivec.size(); ++ix, --cnt)
    ivec[ix] = cnt;
Run Code Online (Sandbox Code Playgroud)

我不认为这是一个恰当的例子,因为这里的逃避和副作用的顺序并不重要.逗号运算符只允许分离递增和递减表达式,这是逗号运算符的常见用法,但不是本书中本节的用意.更好的例子显示在cppreference.com上(请向下滚动到标题内置逗号运算符).

我真正想到的是以下练习:

练习4.31本节中的程序使用前缀增量和减量运算符.解释为什么我们使用前缀而不是后缀.使用后缀版本需要进行哪些更改?使用后缀运算符重写程序.

在这种情况下,没有特殊的理由在postfix运算符上优先使用前缀.评估顺序无关紧要.对simple类型类型的对象的操作vector<int>::size_type不应该在实践中使用前缀而不是后缀,因此在性能很重要的情况下,优先选择前缀而不是后缀.

为了向您提供完整的上下文,请参阅本书中的部分:

4.10逗号运算符
逗号操作符需要两个操作数,它评估由左到右.与逻辑AND和逻辑OR以及条件运算符一样,逗号运算符保证其操作数的计算顺序.

评估左侧表达式并且其结果被删除.逗号表达式的结果是其右侧表达式的值.如果右手操作数是左值,则结果是左值.逗号运算符的一个常见用法是for循环:

vector<int>::size_type cnt = ivec.size();  
// assign values from size...1 to the elements in ivec  
for(vector<int>::size_type ix = 0; ix != ivec.size(); ++ix, --cnt) …
Run Code Online (Sandbox Code Playgroud)

c++ operators

11
推荐指数
1
解决办法
1441
查看次数

通过libstdc ++进行调试

我在GNU/Linux上使用gcc,安装了libc和libstd ++的调试文件和头文件.但我不知道如何告诉gdb使用它们的源代码,特别是调试到libstd ++.libstdc ++本身的源代码似乎是以复杂的结构提供的.我认为目录命令是正确的选择.我在这里使用Debian/Ubuntu并将apt-get source libstdc ++ 6的源代码下载到我的home目录中.

我很确定我不需要为Fedora采取特殊措施(几年前).也许Fedora是以特殊方式准备的.因此,我会对适合每个发行版的一般说明感到高兴.

谢谢

更新
我想通了,我需要编译-D_GLIBCXX_DEBUG-g,所以编译命令如下$ g++ -o test test.cpp -g -D_GLIBCXX_DEBUG.

此外,我收到了关于丢失漂亮打印机的警告,我按照此处的说明解决了这个问题:http: //gcc.gnu.org/onlinedocs/libstdc++/manual/debug.html#debug.gdb

现在我可以调试到libstdc ++,但我总是收到这条消息:

Breakpoint 1, main () at test.cpp:9
9       string str = "str";
(gdb) s
std::allocator<char>::allocator (this=0x7fffffffe1e0)
    at /build/buildd/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/bits/allocator.h:104
104 /build/buildd/gcc-4.7-4.7.2/build/x86_64-linux-gnu/libstdc++-v3/include/bits/allocator.h: No such file or directory.
(gdb) s
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (
    this=0x7fffffffe1c0, __s=0x402930 "str", __a=...)
    at /usr/include/c++/4.7/bits/basic_string.tcc:217
217                    __s + npos, __a), __a)
Run Code Online (Sandbox Code Playgroud)

我不需要将gdb中的 …

c++ debugging libstdc++

10
推荐指数
1
解决办法
4951
查看次数

为什么允许new运算符返回*void到每个指针类型?

在C++中,不允许在没有显式强制转换的情况下为任何整数指针分配void*指针.这需要使用static_cast.

但这是怎么回事:

int* iptr = new int;
Run Code Online (Sandbox Code Playgroud)

我知道新的运算符定义如下:

void* operator new(size_t);
Run Code Online (Sandbox Code Playgroud)

C++如何处理这个问题?我知道这是一个基本问题,但很重要.我也知道低级代码必须使用void.但这项任务如何合法?iptr是指向int的指针,new返回指向void的指针,它应该触发"错误:从'void*'到'int*'[-fpermissive]"无效转换的消息.

c++

9
推荐指数
1
解决办法
3128
查看次数

C++ getline()不需要命名空间声明

为什么getline()来自本地范围内的头字符串并且可以使用:

#include <iostream>
#include <string>

int main() {
    std::string str;
    getline(std::cin, str);
    std::cout << str << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这适用于gcc.但为什么?它在头字符串中定义,它应该要求我使用std :: getline()而不是getline().

c++ scope

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

为libstdc ++生成CTAGS(来自当前的GCC)

我知道基于LLVM的YoucompleteMe,但我想使用OmniCppComplete.如果我使用C++ 的修改标头,这很好用.此修改后的标头已过时,并且不包含C++ 11中的任何内容.

如果注意到我可以自己修改我的标题,例如:

$ find . -name '*.h' | xargs sed -i 's/__STL_BEGIN_NAMESPACE/namespace std {/'
$ find . -name '*.h' | xargs sed -i 's/__STL_END_NAMESPACE/}/'
Run Code Online (Sandbox Code Playgroud)

或使用此设置:

let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
Run Code Online (Sandbox Code Playgroud)

两者都不起作用,当然大多数标头没有和任何文件扩展名.我已经尝试使用文件列表解决此问题.如何在我当前的GCC(例如/ usr/include/c ++/...)的基础上创建工作CTAGS?常见的方法是什么?

谢谢

这是我得到的,如果我尝试从LIBSTD ++完成一些事情:

std::fs
Omni completion (^O^N^P) Back at original
Ctrl+x, Ctrl+o
Omni completion (^O^N^P) Pattern not found
Run Code Online (Sandbox Code Playgroud)

c++ vim ctags c++11

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

具有整洁代码库的C++应用程序可供学习

我正在寻找一个用C++编写的应用程序,它有一个简洁的代码库,可以学习,甚至可以为它做出贡献.很多用C++编写的应用程序要么非常大,要么做一些非常高级的东西,这只是C++的领域.

大小和形状的优秀候选者将类似于来自Archlinux的pacmanlibalpm,但它是用简单的C编写的,而不是C++.WebKit远远不够大,Protobuf看起来很尴尬.Gnote看起来是一个很好的起点,我也使用GNOME,但我不确定它,因为它提供了一个GUI.这让我回到了pacman ; 我自己已经在使用它,它不会分散像GUI这样的东西.

所以我决定寻找一些小而且理智的东西,它提供了一个CLI,我可以自己使用它.我使用术语note + c ++ + stars打开了github的搜索,结果是taskwarrior.简要介绍任务来源(战士)看起来很有希望.

你知道一个用C++编写的整洁项目吗?

谢谢

c++ linux posix command-line-interface

5
推荐指数
0
解决办法
118
查看次数

内部类型的成员变量是否在全局对象内部归零?

使用具有自动存储持续时间的内置类型的未初始化对象是未定义的行为.当然,我强烈建议总是在类类型中初始化内置类型的成员变量.尽管如此,我假设如果类类型的相应对象具有静态存储持续时间(即全局对象),则没有初始化器的内置类型的成员总是初始化为零.我的假设是,具有静态存储持续时间的类类型对象的完整内存被清零.

例:

#include <iostream>
using namespace std;

class Foo {
public:
        int bar;
};

Foo a;

int main() {
        Foo b;
        cout << "a.bar " << a.bar << "\n";
        cout << "b.bar " << b.bar << "\n";
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译:

$ g++ -o init init.cpp -Wall -pedantic # gcc 7.2.1
init.cpp: In function ‘int main()’:
init.cpp:14:31: warning: ‘b.Foo::bar’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  cout << "b.bar …
Run Code Online (Sandbox Code Playgroud)

c++

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

Linux 上的匿名内存是页面缓存的一部分吗?

匿名内存(即程序堆和堆栈)是Linux 上页面缓存的一部分吗?内核的链接文档没有说明这一点。

但是关于页面缓存的维基百科条目包含一个图形(请看右上角),它给我的印象是malloc()在页面缓存中分配动态内存:
Thomas Krenn 的 Linux 存储堆栈图

那有意义吗?关于mmap(),当它用于访问文件时,使用页面缓存是有意义的。通常也用于匿名内存,例如通过?malloc()进行匿名映射。mmap()

我希望得到一些解释。

谢谢。

编辑 2021-03-14
我决定最好在邮件列表上询问内存子系统的内核维护者。幸运的是,马修·威尔科克斯做出了回应并帮助了我。提炼:

  • 匿名内存不由 处理page cache
  • 匿名页面有多种不同的处理方式——可以在LRU lists(最近最少使用)上找到它们,也可以通过page tables. 有点临时的。
  • 维基百科的图表是错误的。它还包含更多缺陷。
  • 如果系统提供交换并且匿名内存被交换 - 它将进入swap cache,而不是page cache

可以在此处此处阅读讨论。

linux memory-management heap-memory linux-kernel

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

是否有可能从cin读取一个空字符串,仍然可以从cin.good()获得真实的?

我的问题基于这个简单的代码:

#include <string>
using namespace std;

int main() {
    string buf;
    while (cin >> buf && !buf.empty()) {
        cout << "input is " << buf << "\n";
    }

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

cin 的operator >>(它是basic_istream类型的对象)读取并丢弃任何前导空格(例如空格,换行符,制表符).然后operator >>读取字符,直到遇到下一个空白字符.运营商最终返回流本身,cin.
如果没有设置至少一个eost,eof,fail或bad,就不可能输入一个空字符串?因此,流与运算符bool转换为false.我认为!buf.empty()在这里是多余的,但这是一个好习惯.有没有办法让cin的iostate保持良好状态并将字符串留空?

用法示例:
1.键入您选择的单词
2.按enter键
3.按Ctrl + d(UNIX上的EOF)或Ctrl + d(Windows上的EOF)

谢谢

c++ cin

4
推荐指数
1
解决办法
526
查看次数

为什么file-command声明,该可执行文件包含"debug_info"

我发现文件> = 5.30gcc> = 6.3已经改变了它的行为.当我编译一个像hello-world这样的基本程序时,file的输出表明elf-executable包含某种"debug_info".

资源:

#include <iostream>
using namespace std;

int main(int argc, char* argv []) {
        cout << "Hello world.\n";
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译:

$ g++ -o hello hello.cpp # notice, no option "-g"
Run Code Online (Sandbox Code Playgroud)

检查:

$ file hello # please scroll to the right hand-side, it is at the very end
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=d03b68ed8618fcb97094b18157054f7cc2030f3c, not stripped, with debug_info …
Run Code Online (Sandbox Code Playgroud)

c c++ linux gcc

4
推荐指数
1
解决办法
190
查看次数