目前,当我们想要破坏具有非常分散的内存分配的复杂对象的非常大的嵌套列表/映射时,我假设C++是调用析构函数并逐个释放内存并且递归,这需要花费大量时间并且效率低下?
在我的情况下,我发现有时需要1分钟或更长时间才能破坏300GB的物体.
操作系统可以杀死占用大量内存的进程,因为它只是释放所有内存而不考虑内部逻辑进程.
我想知道是否有任何现有的C/C++库可以做到这一点?提供维护id系统的自定义内存分配器?这样,如果我指定一个id来为给定的大型STL容器(及其元素)创建一个分配器.当我想要破坏它时,我可以释放分配了指定id的所有内存,并且只丢弃指向外部容器的指针(它会跳过所有的析构函数)?就像我们可以"杀死"一个pid ......
谢谢!
C ++ 17引入了用于过度对齐数据的动态内存分配
除了现有std::max_align_t的基本对齐方式之外,它还增加__STDCPP_DEFAULT_NEW_ALIGNMENT__了运营商新保证的最小对齐方式。
使用MSVC2017 64位编译时,这些常量std::max_align_t的大小为8 __STDCPP_DEFAULT_NEW_ALIGNMENT__,大小为16。
但是,如cppreference:运算符新的全局替换上所述,允许否决运算符new / free 。
查看所有文档,我不清楚是否允许该函数提供新的默认对齐方式,如果允许,则是否允许我们重新定义此常量。
举例说明:
#include <new>
#include <iostream>
#include <cassert>
#include <cstdint>
#include <cstddef>
static_assert(alignof(std::max_align_t) == 8);
static_assert(__STDCPP_DEFAULT_NEW_ALIGNMENT__ == 16);
void * operator new(size_t size)
{
std::cout << "New operator overloading " << std::endl;
void * p = std::malloc((size == 8) ? 16 : size);
assert(std::uintptr_t(p)%16 == 0);
if (size == 8)
{
auto correctedPtr = std::uintptr_t(p) + 8;
return (void*)correctedPtr; …Run Code Online (Sandbox Code Playgroud) 我一直在探索vim,以便能够更好地使用它,同时这样做,在激活相对行号的同时重新激活了行号的显示。
所以我的.vimrc包含以下几行:
" Set line-numbers
set nu
set relativenumber
Run Code Online (Sandbox Code Playgroud)
这一切都很好,尽管vim从0开始计数当前行,而我喜欢从1开始计数。
所以目前看起来像这样:
2 " Something else
1
3 " Set line-numbers
1 set nu
2 set relativenumber
Run Code Online (Sandbox Code Playgroud)
注意:3是当前行号。
假设我想削减行号配置,我必须使用命令3dd,而相对行号为2。有谁知道如何将其更改为:
3 " Something else
2
3 " Set line-numbers
2 set nu
3 set relativenumber
Run Code Online (Sandbox Code Playgroud)
JVApen
我在实际的生产代码中发现了以下内容。我怀疑它实际上有未定义的行为,但是,我在 cppreference 上找不到相关信息。您能否确认这是 UB 或有效代码,以及为什么这是 UB/valid(最好是引用标准)?
#include <vector>
int main(int, char **)
{
auto v = std::vector<int>({1,2,3,4,5});
auto begin = v.begin();
auto outOfRange = begin + 10;
auto end = v.end();
auto clamped = std::min(outOfRange, end);
return (clamped == end) ? 0 : 42;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,begin + 10将创建一个超出std::vector. 但是,没有使用该迭代器,因为它使用std::min.
我经常遇到必须实现自定义复制/移动构造函数的情况.但是一段时间后,会发生类使用新成员进行扩展而且此自定义复制/移动构造函数未更新,因此我正在寻找一种方法来防止代码编译而不更新这些方法.
标题代码:
class MyClass
{
public:
MyClass(const MyClass &rhs);
// ...
private:
std::string _s;
std::unique_ptr<OtherClass> _owned;
bool _b;
};
Run Code Online (Sandbox Code Playgroud)
Cpp代码:
MyClass::MyClass(const MyClass &rhs)
: _s(rhs._s)
, _b(rhs._b)
{
if (rhs._owned)
_owned = rhs._owned->clone();
}
Run Code Online (Sandbox Code Playgroud)
所以,如果我将一些成员添加到MyClass,例如:std::size_t _size;我想要复制构造函数的编译错误.
我目前的解决方案是添加:
static_assert(sizeof(MyClass) == 32, "...");
Run Code Online (Sandbox Code Playgroud)
靠近复制构造函数的这个实现.所有这一切都很好,不幸的是,只有当班级的规模增加时,这才有效.所以,如果我bool _b2;不幸地添加所有编译.
因此,我想检查成员的数量,而不是检查大小.不幸的是我还没有找到这个.有什么建议吗?
我已经考虑过:
bool赞成short,虽然它打破了所有的意图.boolbitset 替换,但不同的值不能有不同的名称static const auto成员数量,希望在添加成员时更新然而,所有这些想法都需要改变代码/指南,所以理想情况下我只想写static_assert(number_of_members<MyClass>::value == 3, "...");任何想法?
我写了一个包裹函数来代替printf的stdio.h.我发现该wrap选项适用于函数stdlib.h,例如malloc或exit.但它没有起作用printf或fprintf.
该选项是否wrap对函数产生影响stdio.h?我怎么能包装一个任意函数?我无法从ld文档中获得有用的指导.
这是代码:
//gcc wrap.c -g -Wl,--wrap,fprintf
int __real_fprintf(FILE *stream, const char *format, ...);
int main(){
fprintf(stderr, "MAIN!\n");
return 0;
}
int __wrap_fprintf(FILE *stream, const char *format, ...){
__real_fprintf(stderr, "WRAP!\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我有这个测试程序,使用#define常量:
#include <stdio.h>
#define FOO 1
int main()
{
printf("%d\n", FOO);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用"Apple LLVM版本10.0.0(clang-1000.11.45.5)"编译时,我得到8432字节的可执行文件.这是装配清单:
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 14
.globl _main ## -- Begin function main
.p2align 4, 0x90
_main: ## @main
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
leaq L_.str(%rip), %rdi
movl $1, %esi
movl $0, -4(%rbp)
movb $0, %al
callq _printf
xorl %esi, %esi
movl %eax, -8(%rbp) ## 4-byte Spill
movl %esi, …Run Code Online (Sandbox Code Playgroud) #include <iostream>
#include <span>
#include <string>
#include <string_view>
#include <vector>
namespace {
template <typename TSpan>
auto createSubSpan1(TSpan &, typename TSpan::iterator start,
typename TSpan::iterator stop) {
static_assert(!std::is_convertible_v<typename TSpan::iterator, std::size_t>);
return TSpan{start, stop};
}
template <typename TSpan>
auto createSubSpan2(TSpan &span, typename TSpan::iterator start,
typename TSpan::iterator stop) {
auto startOffset = std::distance(span.begin(), start);
auto stopOffset = std::distance(span.begin(), stop);
std::cout << startOffset << "-" << stopOffset << std::endl;
static_assert(!std::is_convertible_v<decltype(span.data() + startOffset), std::size_t>);
return TSpan{span.data() + startOffset, span.data() + stopOffset};
}
template <typename TSpan>
auto …Run Code Online (Sandbox Code Playgroud) 我有一个(本地)Web服务器,其配置显示PHP的所有错误(因为调试更容易).
出于某种原因,PHP文件中存在一个小问题,导致如下错误:
Notice: Constant ADODB_BAD_RS already defined in /full/path/to/adodb.inc.php on line 23
Run Code Online (Sandbox Code Playgroud)
由于这些通知并不有意思,至少对于我所包含的图书馆,我想以某种方式忽略它们.
目前我正在通过以下方式执行此操作:
echo "<!-- Ignore some useless warning";
require_once "path/to/adodb.inc.php";
echo "End ignoring warning -->";
Run Code Online (Sandbox Code Playgroud)
这适用于我生成的HTML,但警告仍会出现在生成的HTML代码中.
有没有办法从输出中删除这些行,而不必牺牲为我自己的代码看到类似通知的可能性?
请考虑以下C++程序:
int _Z5func2v;
void func2() {
}
Run Code Online (Sandbox Code Playgroud)
当您尝试编译它时,它会失败:
$ g++ test.cpp -c
/tmp/cc1RDxpU.s: Assembler messages:
/tmp/cc1RDxpU.s:13: Error: symbol `_Z5func2v' is already defined
/tmp/cc1RDxpU.s: Error: .size expression for _Z5func2v does not evaluate to a constant
Run Code Online (Sandbox Code Playgroud)
这是因为程序定义了一个全局变量,该变量与名称重整后的函数名称相同.
我可以想到很多方法可以解决这个问题,其中最简单的方法是在错位名称的开头使用两个下划线(两个下划线保留用于私有实现).
问题是:为什么选择的方案可以实现?