当您希望使用弱指针进行访问时,建议您首先通过锁定来获取指向所指向对象的强指针。如果先前删除了指向的对象,锁定可能不会成功。
在我看来,除非你在打破循环来决定什么是弱指针时犯了错误,否则锁定将会成功。所以你锁定只是为了交叉检查你的设计。
它是否正确?
我看过一些关于缓存的评论,但它们看起来像是对weak_ptr的滥用。但当然,一个人的虐待是另一个人的创新。我想听听意见。
我有一些本机C ++类库,这些库已经包装在C ++ .NET中,然后从C#中调用(三层!)。
我可以从C ++ .NET抛出异常,并愉快地在C#中捕获它们。麻烦的是,我可以捕获本机C ++异常的唯一方法是捕获System.Exception,这很好,但是在从std :: exception到System.Exception的转换中,我丢失了有关错误的绝大多数信息(对于错误消息示例!)。我可以在C ++ .NET层中捕获本机异常,然后将其作为.NET异常重新抛出,但这是一种侵入式解决方案,需要我在每个C ++ .NET方法调用周围放置try-catch块(以捕获本机异常并重新抛出)。 。
是否有替代方法可以解决此问题,否则我将不得不弄脏我的手...
当声明模板参数是typename/ class必要的时(因为语言无法使用我在下面建议的diff语法).我知道模板参数可以是整数,所以你必须选择默认为int或typename/ class但仍然.
即为什么不呢
template <T>
T max(T a, T b) {
return a > b ? a : b;
}
Run Code Online (Sandbox Code Playgroud)
代替
template <typename T>
T max(T a, T b) {
return a > b ? a : b;
}
Run Code Online (Sandbox Code Playgroud)
和
template<T, size_t n>
size_t array_size(const T (&)[n]) {
return n;
}
Run Code Online (Sandbox Code Playgroud)
代替
template<typename T, size_t n>
size_t array_size(const T (&)[n]) {
return n;
}
Run Code Online (Sandbox Code Playgroud) 码:
struct A
{
private:
A() = default; // Version 1.
};
struct B : public A
{};
struct C
{
private:
C() {}; // Version 2.
};
struct D : public C
{};
int main()
{
B b; // Compiles under g++ 4.7.2
D d; // Compilation error under g++ 4.7.2
}
Run Code Online (Sandbox Code Playgroud)
还有两种情况(使用gcc 4.7.2):
D::D()是私有的.问题:如果我使用默认构造函数,为什么问题会消失?如果A有私有构造函数,则其他类永远不能创建实例A,甚至不能创建其派生类,而不管其构造函数实现的"默认性".
我搜索了这个,但我真的不明白答案.
我对C++完全不熟悉,我想要实现的是有一个抽象类作为我的对象类型的基类,这样我就可以将我的对象存储在抽象类类型的指针数组中而不是使用void *.此外,我的对象共享一些常见的成员函数,这些函数可以通过抽象类实现轻松减少我的代码库.
但是,我对抽象类的构造函数和析构函数感到困惑.
抽象类实际上并不需要构造函数,因为可传递的参数对于两者都是通用的,需要在派生类中使用所述参数进行不同的操作以正确设置受保护的属性(矩阵的大小).那么,没有构造函数可以吗?另外,因为我没有构造函数,析构函数应该是什么?
我说一个实现虚拟析构函数的答案.但是,我不确定这意味着什么,并且讨论了潜在的内存泄漏,只要派生类重新实现了析构函数,就不会有任何内容泄漏.所以,这确实意味着我可以实现一个虚拟的decstructor,然后在派生的对象中说Foo,Bar我只是实现~Foo并~Bar防止内存泄漏(假设它们当然是正确的)?我不相信我理解派生类中的重新实现意味着什么.
考虑在Centos 7虚拟机或容器中构建和发布C++项目时的情况.默认gcc为Centos 7是4.8.为了允许开发人员使用现代C++,最新版本gcc(例如6.3)安装在作为CI服务器运行的Centos 7中.这提供了-std=c++14支持.
[builder@f7279ae9f33f build (master %)]$ /usr/bin/c++ -v 2>&1 | grep version
gcc version 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
[builder@f7279ae9f33f build (master %)]$ /opt/rh/devtoolset-6/root/usr/bin/c++ -v 2>&1 | grep version
gcc version 6.3.1 20170216 (Red Hat 6.3.1-3) (GCC)
export CXX=/opt/rh/devtoolset-6/root/usr/bin/c++
make all -j4
...
Run Code Online (Sandbox Code Playgroud)
这是编译和链接命令的简短示例:
[ 78%] Building CXX object CMakeFiles/ucsdos.dir/src/merge_operator_string.cpp.o
/opt/rh/devtoolset-6/root/usr/bin/c++ -Ducsdos_EXPORTS -I/home/builder/src/dos/libucsdos/./src -I/home/builder/src/dos/libucsdos/./include -I/home/builder/src/dos/libucsdos/build/schema/cpp -I/home/builder/src/dos/libucsdos/build/schema -isystem /usr/local/include -O2 -g -DNDEBUG -fPIC -frtti …Run Code Online (Sandbox Code Playgroud) 当用vs2010编译(和执行)这个c ++代码时,我甚至在它甚至可以向控制台一瞥"Start"之前就得到了一个堆栈溢出异常.
所有我使用的标题,文件都包含在stdafx.h中,但(包括标题,文件直接当同样的问题),这里显然不是问题.
堆栈跟踪如下:
> msvcr100d.dll!__set_flsgetvalue() Zeile 145 + 0xc Bytes C
msvcr100d.dll!_getptd_noexit() Zeile 500 C
msvcr100d.dll!_getptd() Zeile 523 + 0x5 Bytes C
msvcr100d.dll!_LocaleUpdate::_LocaleUpdate(localeinfo_struct * plocinfo) Zeile 243 + 0x5 Bytes C++
003efe3c()
TerrainGenerator.exe!pre_cpp_init() Zeile 298 + 0x21 Bytes C
Run Code Online (Sandbox Code Playgroud)
任何帮助都将非常感激,我是c ++的绝对初学者,正如你可能在代码风格中看到的那样,我尝试了一切以摆脱这个恼人的问题,例如甚至没有声明一个额外的功能等等. ..请帮助我,不要犹豫,询问您是否需要其他信息.提前致谢.
#include "stdafx.h"
int main(int argc, char* argv[])
{
puts("Start");
const int res = 4096;
srand(time(NULL));
uint16_t data[(res+1)*(res+1)];
uint16_t variance = 2000;
int seed = 1337;
data[0] = ((seed>>1)+(int)(rand()/(RAND_MAX*(seed+(seed>>1)))));
data[res] = ((seed>>1)+(int)(rand()/(RAND_MAX*(seed+(seed>>1)))));
data[res*res] = ((seed>>1)+(int)(rand()/(RAND_MAX*(seed+(seed>>1)))));
data[res*(res+1)] = ((seed>>1)+(int)(rand()/(RAND_MAX*(seed+(seed>>1))))); …Run Code Online (Sandbox Code Playgroud) 我正在研究一些与安全有关的事情,现在我正在玩我自己的堆栈.我正在做的事应该非常简单,我甚至都没有尝试执行堆栈,只是为了表明我可以控制64位系统上的指令指针.我已经关闭了所有我能够使用它的保护机制(NX-bit,ASLR,也用-fno-stack-protector -z execstack编译).我没有那么多64位汇编的经验,花了一些时间搜索和试验自己后,我想知道是否有人能够解决我遇到的问题.
我有一个程序(下面的源代码),它只是将一个字符串复制到一个没有边界检查的堆栈驻留缓冲区.但是,当我用一系列0x41覆盖时,我希望看到RIP设置为0x4141414141414141,而我发现我的RBP设置为此值.我确实遇到了分段错误,但是在执行RET指令时RIP不会更新为此(非法)值,即使RSP设置为合法值也是如此.我甚至在GDB中验证了在RET指令之前有可读存储器在RSP处包含一系列0x41.
我的印象是LEAVE指令:
MOV(E)SP,(E)BP
POP(E)BP
但是在64位上,"LEAVEQ"指令似乎(类似):
MOV RBP,QWORD PTR [RSP]
我认为这只是通过在执行该指令之前和之后观察所有寄存器的内容来实现的.LEAVEQ似乎只是RET指令的上下文相关名称(GDB的反汇编程序给它),因为它仍然只是一个0xC9.
RET指令似乎与RBP寄存器有关,可能是解除引用它?我认为RET确实(类似):
MOV RIP,QWORD PTR [RSP]
但是就像我提到的那样,似乎取消引用RBP,我认为这样做是因为当没有其他寄存器似乎包含非法值时,我得到了分段错误.
该计划的源代码:
#include <stdio.h>
#include <string.h>
int vuln_function(int argc,char *argv[])
{
char buffer[512];
for(int i = 0; i < 512; i++) {
buffer[i] = 0x42;
}
printf("The buffer is at %p\n",buffer);
if(argc > 1) {
strcpy(buffer,argv[1]);
}
return 0;
}
int main(int argc,char *argv[])
{
vuln_function(argc,argv);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
for循环只是用0x42填充缓冲区的合法部分,这使得在溢出之前很容易在调试器中看到它.
调试会话的摘录如下:
(gdb) disas vulnerable
Dump of assembler code for function vulnerable:
0x000000000040056c …Run Code Online (Sandbox Code Playgroud) 嘿所以我正在制作一个以字符串作为键和成员函数指针作为值的映射.我似乎无法弄清楚如何添加到地图,这似乎没有工作.
#include <iostream>
#include <map>
using namespace std;
typedef string(Test::*myFunc)(string);
typedef map<string, myFunc> MyMap;
class Test
{
private:
MyMap myMap;
public:
Test(void);
string TestFunc(string input);
};
#include "Test.h"
Test::Test(void)
{
myMap.insert("test", &TestFunc);
myMap["test"] = &TestFunc;
}
string Test::TestFunc(string input)
{
}
Run Code Online (Sandbox Code Playgroud) 我在gcc 4.7.1(std = c ++ 11)中遇到了预处理程序令牌粘贴运算符的问题.即,请考虑以下代码:
// Create a name for a global map (this works)
#define GLOBAL_MAP(name) g_map_ ## name // This works fine
// Now, namespace qualify this map (this fails to compile when used)
#define NS_QUAL_GLOBAL_MAP(name) SomeNamespace:: ## GLOBAL_MAP(name)
Run Code Online (Sandbox Code Playgroud)
使用场景 - 首先是地图定义:
std::map<std::string,std::string> GLOBAL_MAP(my_map);
namespace SomeNamespace
{
std::map<std::string,std::string> GLOBAL_MAP(my_map);
}
Run Code Online (Sandbox Code Playgroud)
现在用法:
void foo()
{
bar(GLOBAL_MAP(my_map)); // This compiles fine
baz(NS_QUAL_GLOBAL_MAP(my_map)); // This fails to compile with:
// error: pasting "::" and "NAME_MAP" does not give a
// …Run Code Online (Sandbox Code Playgroud)