小编Ban*_*nex的帖子

是否允许编译器优化堆内存分配?

考虑以下使用的简单代码new(我知道没有delete[],但它与此问题无关):

int main()
{
    int* mem = new int[100];

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

是否允许编译器优化new呼叫?

在我的研究中,g ++(5.2.0)和Visual Studio 2015不会优化new呼叫,而clang(3.0+)则可以.所有测试都是在启用完全优化的情况下进行的(-O3用于g ++和clang,用于Visual Studio的发布模式).

是不是new在引擎盖下进行系统调用,使编译器无法(并且非法)优化它?

编辑:我现在已经从程序中排除了未定义的行为:

#include <new>  

int main()
{
    int* mem = new (std::nothrow) int[100];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

clang 3.0不再优化它,但后来的版本确实如此.

编辑2:

#include <new>  

int main()
{
    int* mem = new (std::nothrow) int[1000];

    if (mem != 0)
      return 1;

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

clang总是返回1.

c++ optimization gcc clang language-lawyer

66
推荐指数
4
解决办法
4867
查看次数

编译器如何在不知道编译时的大小的情况下分配内存?

我写了一个C程序,它接受来自用户的整数输入,用作整数数组的大小,并使用该值声明给定大小的数组,我通过检查数组的大小来确认它.

码:

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int n;
    scanf("%d",&n);
    int k[n];
    printf("%ld",sizeof(k));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

而且令人惊讶的是它是正确的!该程序能够创建所需大小的数组.
但是所有静态内存分配都是在编译时完成的,并且在编译期间,其值n是未知的,那么为什么编译器能够分配所需大小的内存呢?

如果我们能够分配所需的内存就是这样,然后有什么用使用动态分配的malloc()calloc()

c memory arrays c99 variable-length-array

66
推荐指数
3
解决办法
4308
查看次数

在Visual Studio外部启动时,程序运行速度较慢

我注意到我的程序有一些奇怪的行为.我使用Visual Studio Professional 2013 Update 1在C++中编写它,它由一个exe应用程序组成,该应用程序链接多个DLL并调用这些DLL中定义的函数.

在我的主程序(由几千行代码组成)中,我调用了一个DLL函数(让我们调用它DLLFunction()),然后计算该调用所花费的时间,如下所示:

auto beginTime = std::chrono::high_resolution_clock::now();

DllFunction();

auto endTime = std::chrono::high_resolution_clock::now();

long long totalTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
Run Code Online (Sandbox Code Playgroud)

我注意到在Visual Studio外部启动它需要更长的时间.例如:

在Visual Studio 中的调试中运行它并附带调试器 - >~50 ms

在Visual Studio 中的发布中运行它并附带调试器 --->~25 ms

在Visual Studio 中的发布中运行它而不附加调试器 --->~20 ms

Visual Studio 外部运行它(发布版本)--->~80 ms

正如您所看到的,在Visual Studio外部的发布中运行它实际上比运行附加调试器的调试版本花费更长的时间!

有问题的DLL由同一个编译器构建在同一个解决方案中,我已经仔细检查过我启动应用程序的目录中的所有DLL都是正确的.

这种行为可能是什么原因?

编辑5:主应用程序生成另一个控制台应用程序并使用命名管道与它通信.原来,没有产生另一个应用程序使得DLL在Visual Studio外快速调用.

但是,在Visual Studio内部和外部都会生成相同的应用程序,所以我不明白为什么它会减慢Visual Studio外部的其他调用.

编辑4:事实证明,只有当我将函数调用放在我的主程序的代码的某些部分时才出现这种缓慢的行为,所以它必须是与此相关的问题.这是很多行,但我会继续研究.

无论如何,感谢您的建议,它们对于识别问题很有用.

编辑3:使用QueryPerfomanceCounter进行测量:

在Visual Studio中测量的CPU周期(~50k)是外部的一半(~110k)(顺便说一下,QueryPerfomanceCounter()实际CPU周期返回的CPU周期是多少?). …

c++ dll visual-studio-2013

15
推荐指数
1
解决办法
1326
查看次数

制作'干净'要求确认

有没有办法让命令make clean需要用户确认?我错误地执行了它,现在我必须等待6个小时才能再次完成构建.

Makefile小号被创建cmake.

期望的工作流程:

> make clean
> [make] Are you sure you want to remove all the built files? [Y/N]
> N
> [make] Target 'make clean' not executed.

> make clean
> [make] Are you sure you want to remove all the built files? [Y/N]
> Y
> [make] Target 'make clean' executed.
Run Code Online (Sandbox Code Playgroud)

makefile cmake

12
推荐指数
1
解决办法
2733
查看次数

正则表达式只匹配一些文件名

使用std ::正则表达式,并给予文件路径,我想只匹配结束的文件名.txt和不是形式_test.txt.txtTEMP.任何其他下划线都没问题.

所以,例如:

  • somepath/testFile.txt 应该匹配.
  • somepath/test_File.txt 应该匹配.
  • somepath/testFile_test.txt 不应该匹配.
  • somepath/testFile.txtTEMP 不应该匹配.

这种模式的正确正则表达式是什么?

我尝试过的:

(.*?)(\.txt)--->匹配任何以.txt.结尾的文件路径.

要排除包含_test我尝试使用否定外观的文件:

(.*?)(?!_test)(\.txt)

但它没有用.

我也试过负面的lookbehind,但MSVC14(Visual Studio 2015)std::regex_error在创建正则表达式时抛出一个异常,所以我不确定它是否不受支持或者我使用了错误的语法.

c++ regex c++11

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

在扩展内联ASM中调用printf

我试图在64位Linux上的GCC扩展内联ASM中输出相同的字符串两次.

int main()
{
    const char* test = "test\n";

    asm(
        "movq %[test], %%rdi\n"    // Debugger shows rdi = *address of string*  
        "movq $0, %%rax\n"

        "push %%rbp\n"
        "push %%rbx\n"
        "call printf\n"         
        "pop %%rbx\n"
        "pop %%rbp\n"

        "movq %[test], %%rdi\n" // Debugger shows rdi = 0
        "movq $0, %%rax\n"

        "push %%rbp\n"
        "push %%rbx\n"
        "call printf\n"     
        "pop %%rbx\n"
        "pop %%rbp\n"
        : 
        :  [test] "g" (test)
        : "rax", "rbx","rcx", "rdx", "rdi", "rsi", "rsp"
        );

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

现在,字符串只输出一次.我尝试了很多东西,但我想我错过了关于调用约定的一些注意事项.我甚至不确定clobber列表是否正确,或者我是否需要保存和恢复RBPRBX.

为什么字符串不输出两次? …

printf gcc x86-64 inline-assembly calling-convention

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

地址规范形式和指针算术

在符合AMD64标准的体系结构中,地址需要在取消引用之前采用规范形式.

英特尔手册的3.3.7.1节:

在64位模式中,如果微架构的地址位63到最重要的实现位被设置为全1或全零,则认为地址是规范形式.

现在,当前操作系统和体系结构中最有意义的实现位是第47位.这给我们留下了48位的地址空间.

特别是当启用ASLR时,用户程序可能会收到第47位设置的地址.

如果使用指针标记等优化并且高位用于存储信息,则程序必须确保将第48位至第63位设置回取消引用地址之前的第47位.

但请考虑以下代码:

int main()
{
    int* intArray = new int[100];

    int* it = intArray;

    // Fill the array with any value.
    for (int i = 0; i < 100; i++)
    {
        *it = 20;
        it++;   
    }

    delete [] intArray;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在考虑的intArray是,说:

0000 0000 0000 0000 0 111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1100

设置itintArray并增加it一次,并考虑sizeof(int) == …

x86-64 pointer-arithmetic access-violation aslr

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

数据帧中的行阈值

考虑一个示例数据框:

A   B   C   v
5   4   2   3
7   1   3   5
1   2   1   1
Run Code Online (Sandbox Code Playgroud)

如果元素大于或等于v,我想将行的所有元素设置为1 ,否则为0.示例数据框将导致以下结果:

A   B   C   v
1   1   0   3
1   0   0   5
1   1   1   1
Run Code Online (Sandbox Code Playgroud)

我怎样才能有效地做到这一点?列数会更高,我想要一个解决方案,不要求我单独指定列的名称,而是将它应用于所有列(除外v).

我使用for循环的解决方案太慢了.

r

2
推荐指数
1
解决办法
26
查看次数