相关疑难解决方法(0)

调用约定和评估顺序

我知道C++没有指定参数传递给函数的顺序.但是如果我们编写以下代码:

void __cdecl func(int a, int b, int c)
{
       printf("%d,%d,%d", a,b,c);
}
int main()
{
   int i=10;
   func(++i, i, ++i);
}
Run Code Online (Sandbox Code Playgroud)

我们能否可靠地说输出是12,11,11因为__cdecl确保参数传递顺序是从右到左?

c++ arguments function

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

为什么strlen与s的大小不同,为什么cout char显示的是字符而不是数字?

我写了一段代码来计算'e'一堆单词中有多少个字符.

例如,如果我输入"I read the news",那么e存在多少个的​​计数器应为3.

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    char s[255],n,i,nr=0;
    cin.getline(s,255);

    for(i=1; i<=strlen(s); i++)
    {
        if(s[i-1]=='e') nr++;
    }
    cout<<nr;

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

我有两个关于C++中字符的不清楚的事情:

  1. 在上面的代码中,如果我strlen(s)用255 替换,我的代码就不起作用了.我只能输入一个单词,程序就会停止.我在学校被教过strlen(s)这个字符串的长度s,在这种情况下,就像我宣称的那样,是255.那么,为什么我不能只输入255而不是strlen(s)

  2. 如果我正常运行上面的程序,它不会显示一个数字,就像它应该做的那样.它向我展示了一个角色(我相信它来自ASCII表,但我不确定),就像一颗心或一颗钻石.它应该e从单词中打印出的数字.

有人可以向我解释这些吗?

c++ ascii character

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

C++移位运算符优先级怪异

请考虑以下代码:

typedef vector<int> intVec;

intVec& operator<<(intVec& dst, const int i) {
    dst.push_back(i);
    return dst;
}
int intResult0() {
    return 23;
}
int intResult1() {
    return 42;
}

// main
intVec v;
v << intResult0() << intResult1();
Run Code Online (Sandbox Code Playgroud)

奇怪的是,编译器生成代码,该代码评估intResult1 BEFORE intResult0(使用最新的VC和gcc进行测试).为什么编译器会这样做?通过这样做,评估和使用各个值之间的时间(不必要地)增加(α),即首先获取42,但最后推送到矢量.C++标准是否规定了这一点?

c++ operator-overloading

4
推荐指数
3
解决办法
739
查看次数

为什么C++会以这种方式运行?

#include<stdio.h>

class A { public: int a;};

class B: public A {
    int c; 
    int d;
};

int main() {

    A* pA = new B[10];
    B* pB = new B[10];

    printf("\n%d", pA->a);
    pA++;
    printf("\n%d", pA->a);  // prints junk value

    printf("\n\n%d", pB->a);
    pB++;
    printf("\n%d", pB->a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

第二个printf打印垃圾值.

它应该指出它指向一个类型的对象B并通过它增加sizof(B).

为什么不会发生这种情况?

c++ arrays oop object

4
推荐指数
3
解决办法
439
查看次数

指向临时变量的C++引用?

class ClassB {
    int m_b;
public:
    ClassB(int b) : m_b(b) {}
    void PrintClassB() const {
        cout << "m_b: " << m_b << endl;
    }
};


int main(int argc, char* argv[])
{
    const ClassB &af = ClassB(1);
    af.PrintClassB(); // print m_b: 1 with vs2008 & gcc 4.4.3
}
Run Code Online (Sandbox Code Playgroud)

鉴于上面的代码,我很难理解这段代码:

Q1>这条线是什么意思?

const ClassB &af = ClassB(1);
Run Code Online (Sandbox Code Playgroud)

这是我的理解:

af refers to a temporary variable ClassB(1) and after the
Run Code Online (Sandbox Code Playgroud)

执行此行,临时变量被销毁,af指的是未定义的变量.在此过程中,不会调用任何复制构造函数.

那为什么我们仍然可以发出以下声明并获得结果呢?

af.PrintClassB(); // print m_b: 1 with vs2008 & gcc 4.4.3
Run Code Online (Sandbox Code Playgroud)

c++

4
推荐指数
2
解决办法
3984
查看次数

为什么不能在函数参数列表中使用alloca?

引用第2 BUGS节,从手册页alloca(3)

在许多系统alloca()中不能在函数调用的参数列表中使用,因为保留的堆栈空间alloca()将出现在函数参数的空间中间的堆栈中.

我没看到这会怎么样.以下面的代码为例:

void f(int a, void * b, int c);

int
main(void)
{
    f(1, alloca(100), 2);
}
Run Code Online (Sandbox Code Playgroud)

根据我的理解,alloca将堆栈帧扩展为main100字节(通过修改堆栈指针寄存器),然后指向堆栈存储器块(以及2 int秒)的指针在堆栈帧上传递f.所以分配的空间不应该在中间a,b或者c实际上它应该在不同的帧上(main在这种情况下,它在帧上).

那么这里的误解是什么?

c stack allocation alloca

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

在双重检查锁定中解释竞争条件

void undefined_behaviour_with_double_checked_locking()
{
    if(!resource_ptr)                                    #1
    {
        std::lock_guard<std::mutex> lk(resource_mutex);  #2
        if(!resource_ptr)                                #3
        {
           resource_ptr.reset(new some_resource);        #4
        }
    }
    resource_ptr->do_something();                        #5
}
Run Code Online (Sandbox Code Playgroud)

如果一个线程看到另一个线程写入的指针,它可能看不到新创建的some_resource实例,导致调用do_something()操作不正确的值.这是由C++标准定义为数据竞争的竞争条件类型的示例,因此被指定为未定义的行为.

问题 >我已经看到上面的解释为什么代码具有导致竞争条件的双重检查锁定问题.但是,我仍然很难理解问题所在.也许一个具体的双线程逐步工作流程可以帮助我真正理解上面代码的竞争问题.

本书提到的解决方案之一如下:

std::shared_ptr<some_resource> resource_ptr;
std::once_flag resource_flag;

void init_resource()
{
    resource_ptr.reset(new some_resource);
}
void foo()
{
    std::call_once(resource_flag,init_resource); #1
    resource_ptr->do_something();
}
#1 This initialization is called exactly once
Run Code Online (Sandbox Code Playgroud)

欢迎任何评论 - 谢谢

c++ multithreading race-condition double-checked-locking

3
推荐指数
2
解决办法
608
查看次数

为什么我不能在C++中初始化一个将自身纳入其初始值的对象?

当我遇到以下错误键入的代码时,我正在调试程序,类似于以下内容:

//Original (wrong)
std::string first("Hello");
std::string second = first + second;

//Instead of this (correct)
std::string first("Hello");
std::string second = first + something_else;
Run Code Online (Sandbox Code Playgroud)

显然我并没有尝试这样做(我想不出为什么有人会想这样做),但它让我思考.它看起来不像原版应该工作,我认为它是未定义的.实际上,这是我问题的根源.

要使问题更加通用,请考虑以下事项:

SomeType a;
SomeType b = a + b;
Run Code Online (Sandbox Code Playgroud)

行为是否未定义仅仅是因为b尚未初始化(请参阅此答案)?

如果行为未定义,那么我真正的问题是,为什么?

对于某些标准容器,这只是未定义的std::string,或者是否在更一般意义上未定义(STL类,用户定义的类,POD,基本类型)?

该标准的哪一部分适用于此?

如果需要,假设这是c ++ 11.

c++ string undefined-behavior

3
推荐指数
1
解决办法
128
查看次数

是否有办法警告行为不端的指定初始化器?

C99引入了结构指定的初始化器的概念.例如,给定:

typedef struct {
    int c;
    char a;
    float b;
} X;
Run Code Online (Sandbox Code Playgroud)

我可以初始化为:X foo = {.a = '\1', .b = 2.0F, .c = 4};并且调用:printf("c = %d\na = %hhu\nb = %f", foo.c, foo.a, foo.b);将输出:

c = 4
a = 1
b = 2.000000

这里提到这有分配给的"令人惊讶的行为" c,然后ab独立我指定的初始的顺序.

如果我有这样的函数,这将成为一个真正的问题:

int i = 0;

int f() {
    return ++i;
}

int g() {
    i += 2;
    return i;
}

int h() {
    i += 4; …
Run Code Online (Sandbox Code Playgroud)

c warnings designated-initializer initialization-list

3
推荐指数
1
解决办法
485
查看次数

在QObject *和void *之间转换

我正在使用QT 5.7,并且由于必须使用库,因此需要将QObject(派生类)与void指针进行相互转换。

几个定义。我有一个仅接受空指针的函数,而我的类是从QObject派生的:

void oneFunction(void *obj);

class MyObj : public QObject
{
    ...
};
Run Code Online (Sandbox Code Playgroud)

然后创建并填充一个对象:

MyObj *ptr = new MyObj(parent);
ptr->.......
Run Code Online (Sandbox Code Playgroud)

在某些时候,我将其转换为void指针,因为我必须将其传递给函数。该转换是自动完成的:

oneFunction(ptr);
Run Code Online (Sandbox Code Playgroud)

然后,一段时间后,我收到了我传递的指针,并且需要将其转换回原始类。指针未被函数修改:

void callbackFromOneFunction(void *theOldPointer)
{
    MyObj *oldPtr = qobject_cast<MyObj*>(static_cast<QObject*>(theOldPointer));
    if (oldPtr != nullptr)
    {
        ... Now it's back, so use it
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,整个过程对吗?您发现一些问题/泄漏吗?有更好的解决方案吗?

谢谢

c++ qt pointers casting

3
推荐指数
1
解决办法
1114
查看次数