小编Pow*_*ice的帖子

为什么析构函数需要一个未删除的对象?

struct A
{
    ~A() = delete;
};

int main()
{
    new A{};
}
Run Code Online (Sandbox Code Playgroud)

这无法编译,并显示错误消息:

错误:使用已删除的函数'A :: ~A()'new A {};

据我所知,我没有破坏对象,为什么它试图调用析构函数?

用GCC 8.1.0编译

g++ -std=c++17 -O2
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer

58
推荐指数
1
解决办法
2582
查看次数

终身规则结束时的差异?

https://en.cppreference.com/w/cpp/language/lifetime注释部分有这个代码,这里转载:

struct A {
  int* p;
  ~A() { std::cout << *p; } // if n outlives a, prints 123
};
void f() {
  A a;
  int n = 123; // if n does not outlive a, this is optimized out (dead store)
  a.p = &n;
}
Run Code Online (Sandbox Code Playgroud)

在本笔记部分试图说些什么?

根据我的理解,代码是UB(或者是它),因为它显然n不会超过a.

它是什么意思:

非类对象(存储持续时间结束)和类对象(构造的逆序)之间的生命周期规则的差异很重要

但它没有说明如何.

整个部分让我很困惑.

c++ undefined-behavior language-lawyer

33
推荐指数
2
解决办法
1056
查看次数

对最长增长子序列的潜在O(n)解

我试图回答这个问题,只使用递归(动态编程) http://en.wikipedia.org/wiki/Longest_increasing_subsequence

从文章和SO周围,我意识到最有效的现有解决方案是O(nlgn).我的解决方案是O(N),我找不到它失败的情况.我包括我使用的单元测试用例.

import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.Test;

public class LongestIncreasingSubseq {

    public static void main(String[] args) {
        int[] arr = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15, 1};
        getLongestSubSeq(arr);
    }

    public static List<Integer> getLongestSubSeq(int[] arr) {
        List<Integer> indices = longestRecursive(arr, 0, arr.length-1);
        List<Integer> result = new ArrayList<>();
        for (Integer i : indices) {
            result.add(arr[i]);
        }

        System.out.println(result.toString());
        return result;
    }

    private static List<Integer> longestRecursive(int[] arr, …
Run Code Online (Sandbox Code Playgroud)

java algorithm memoization dynamic-programming time-complexity

19
推荐指数
2
解决办法
4448
查看次数

放置 - 新地址对齐

根据https://isocpp.org/wiki/faq/dtors#placement-new ,传递给placement-new的地址必须正确对齐.但它给出的例子似乎与此相矛盾.

char memory[sizeof(Fred)];
Run Code Online (Sandbox Code Playgroud)

这个缓冲区很可能不会与Fred对齐,因为它是一个愚蠢的char[],所以memory可以指向几乎任何地方.然后它在这个地址上做了一个新的位置.

这个例子是否与DANGER脚注中的对齐要求相矛盾?

这导致了一个相关的问题:

如何创建一个为类型对齐的缓冲区(堆栈或堆)T(用于一个或多个T对象的placement-new)?

缓冲区我的意思是一个char[]void*一些大小的缓冲区,而不是T[]因为那将是对象分配,这会破坏后续进行放置的点.

谢谢.

c++ memory-management memory-alignment undefined-behavior

12
推荐指数
2
解决办法
1232
查看次数

临时对象原来是const吗?

这个代码是UB吗?

struct A
{
 void nonconst() {}
};

const A& a = A{};
const_cast<A&>(a).nonconst();
Run Code Online (Sandbox Code Playgroud)

换句话说,(临时)对象原来是const?我已经查看了标准,但找不到答案,所以会对相关部分的引用表示赞赏.

编辑:对于那些说A{}不是的人const,你能做到A{}.nonconst()吗?

c++ const undefined-behavior language-lawyer temporary-objects

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

使用已删除的指针地址

(*)据我所知,标准允许实现修改运算delete符的操作数,但是大多数实现都不这样做.

int* ptr = new int(0);
delete ptr; //delete is allowed to modify ptr, for example set it to 0
std::cout << ptr; // UB?
Run Code Online (Sandbox Code Playgroud)

承认(*),是否以ptr(以打印的形式)明确定义的读数?

如果delete修改ptr,是否允许设置陷阱值,这将使读取ptrUB?

c++ undefined-behavior

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

取消引用null并不总是UB?

我一直都知道标准规定解除引用null是UB 的事实.然而,

(链接1)

p = 0;*P; 本质上不是一个错误.

并提供链接

(链接2)

当p为null时,*p不是错误,除非将左值转换为左值

(我认为这是一个错字,可能应该读取左值转换为右值)

Link 1也说

char*p = 0; char*q =&*(p)

是"未定义",我只能阅读定义明确或至少是实现定义

语言律师可以提供有关正在发生的事情的权威解释吗?

c++ undefined-behavior language-lawyer

8
推荐指数
1
解决办法
252
查看次数

Thread.join()的JDK实现

我想知道Java如何实现join()方法来等待线程完成.根据源代码:

public final synchronized void  [More ...] join(long millis)
throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (millis == 0) {
        while (isAlive()) {
            wait(0);
        }

    } else {
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

调用线程在运行线程仍处于活动状态时无限期地获取正在运行的线程的监视器和在线1160的wait().

我的问题是:当线程完成时,who(以及谁调用)notify()或notifyAll(),以便它唤醒调用线程?

要非常清楚,问题是JDK/JVM在哪里调用notify(),而不是在我们的代码中.

谢谢.

java concurrency multithreading jvm

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

向量中的无效迭代器

我知道擦除会在擦除点之后和之后使迭代器无效.考虑:

std::vector<int> vec = {1, 2, 3, 4, 5};
std::vector<int>::iterator it = vec.end() - 1; //last element
vec.erase(vec.begin()); //shift everything one to the left, 'it' should be the new 'end()' ?
std::cout << (it == vec.end()); //not dereferencing 'it', just comparing, UB ?
Run Code Online (Sandbox Code Playgroud)

比较(而不是取消引用)无效的迭代器(it在这种情况下)是未定义的行为吗?如果没有,it == vec.end()保证是真的吗?

编辑:从顶部答案看,如果只是it一个奇异的值,这就是UB .但是在STL迭代器的上下文中,什么是单数和非奇异值?它似乎it是(或曾经)与容器相关联,因此it 非单数形式.

我很感激对此进行进一步的分析,谢谢.

c++ iterator vector undefined-behavior language-lawyer

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

constexpr和未定义的行为

该代码在GCC 8中编译,但不在GCC 7和clang中编译。

constexpr int a = 1;
constexpr int b = --const_cast<int&>(a);
Run Code Online (Sandbox Code Playgroud)

这显然是UB。

我的问题:Standardese对评估包含UB的constexpr有什么看法-此代码应该完全编译吗?

c++ undefined-behavior language-lawyer constexpr

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

2个指针,0个字节的差异但不相等

在C++中,我完全知道指针减法仅在数组中有效,并且下面的代码是未定义的行为.我知道试图推断未定义的行为是毫无意义的,但我相信提出以下问题是有价值的.

#include <cstddef>
#include <iostream>
#include <iomanip>

int main()
{
    long a = 1;
    long b = 1;

    std::cout << (char*)(&b) - (char*)(&a)  << '\n'; //prints 8, ok we're 8 bytes apart

    char* aPlus8 = (char*)&a + 8; //bump up 8 bytes
    char* bPtr = (char*)&b;

    std::cout << "diff in bytes = " << (bPtr - aPlus8)  << '\n';            //prints 0. All good, looks like we're there
    std::cout << "but are they the same? = " << (bPtr …
Run Code Online (Sandbox Code Playgroud)

c++ pointers undefined-behavior

0
推荐指数
1
解决办法
61
查看次数