相关疑难解决方法(0)

sizeof可以返回0(零)

sizeof运算符是否有可能在C或C++中返回0(零)?如果可能的话,从标准的角度来看是否正确?

c c++ sizeof

50
推荐指数
4
解决办法
9881
查看次数

指向零长度数组的指针的属性

考虑

int main()
{
    auto a = new int[0];
    delete[] a; // So there's no memory leak
}
Run Code Online (Sandbox Code Playgroud)

在复制初始化和删除之间,您是否允许读取指针a + 1

此外,该语言是否允许编译器设置anullptr?

c++ language-lawyer

22
推荐指数
2
解决办法
460
查看次数

`std :: string`分配是我目前的瓶颈 - 如何使用自定义分配器进行优化?

我正在编写一个C++ 14 JSON库作为练习,并在我的个人项目中使用它.

通过使用callgrind,我发现在字符串压力测试的连续值创建过程std::string中,当前的瓶颈是动态内存分配.确切地说,瓶颈就是要求malloc(...)制造的std::string::reserve.

我已经读过很多现有的JSON库,比如rapidjson使用自定义分配器来避免malloc(...)字符串内存分配期间的调用.

我试图分析rapidjson的源代码,但是大量额外的代码和注释,以及我不确定我正在寻找什么的事实,对我没什么帮助.

  • 自定义分配器如何在这种情况下提供帮助?
    • 是否在某处预先分配了内存缓冲区(静态?)并std::strings从中获取可用内存?
  • 使用自定义分配器的字符串是否与普通字符串"兼容"?
    • 他们有不同的类型.他们必须"转换"吗?(这会导致性能下降吗?)

代码说明:

  • Str是别名std::string.

c++ string optimization memory-management c++14

13
推荐指数
1
解决办法
2781
查看次数

new A[0]:为具有不可访问构造函数的类初始化具有动态存储持续时间的零大小数组

我有一个 C++ 概念来检查对象数组是否可以动态分配:

template< class T, int N >
concept heap_constructible = requires() {
    delete[] new T[N];
};
Run Code Online (Sandbox Code Playgroud)

我意外地发现,在零大小数组N=0和不可访问的(例如private:)构造函数的情况下,编译器的评估会出现分歧:

class A {
    A();
};

static_assert( !heap_constructible<A, 5> ); // OK everywhere
static_assert( heap_constructible<A, 0> );  // OK in GCC only
Run Code Online (Sandbox Code Playgroud)

只有 GCC 似乎允许零大小分配A-objects。Clang 打印错误:

calling a private constructor of class 'A'
Run Code Online (Sandbox Code Playgroud)

如果概念稍作修改:

template< class T, int N >
concept heap_constructible1 = requires() {
    delete[] new T[N]{}; // note additional empty braced list
};
Run Code Online (Sandbox Code Playgroud)

Clang …

c++ constructor new-operator language-lawyer

13
推荐指数
1
解决办法
352
查看次数

在C++ 11中,如何调用new并为对象保留足够的内存?

我有一个以这种方式描述的类:

class Foo {
    int size;
    int data[0];

public:
    Foo(int _size, int* _data) : size(_size) {
        for (int i = 0 ; i < size ; i++) {
            data[i] = adapt(_data[i]);
        }
    }

    // Other, uninteresting methods
}
Run Code Online (Sandbox Code Playgroud)

我无法改变那门课程的设计.

如何创建该类的实例?在调用构造函数之前,我必须保留足够的内存来存储其数据,因此它必须在堆上,而不是在堆栈上.我想我想要的东西

Foo* place = static_cast<Foo*>(malloc(sizeof(int) + sizeof(int) * size));
*place = new Foo(size, data);  // I mean : "use the memory allocated in place to do your stuff !"
Run Code Online (Sandbox Code Playgroud)

但我找不到办法让它发挥作用.

编辑:正如评论员所注意到的,这不是一个非常好的整体设计(使用非标准技巧data[0]),唉这是一个我不得不使用的库...

c++ memory-management c++11

8
推荐指数
2
解决办法
554
查看次数

operator new的任何实现都会返回指向零大小数组的保护页面的指针吗?

相关:C++ new int [0] - 它会分配内存吗?

该标准在5.3.4/7中说:

当direct-new-declarator中的表达式的值为零时,将调用分配函数以分配不带元素的数组.

......并且,在3.7.3.1/2中:

取消引用作为零大小请求返回的指针的效果是未定义的.

...但是,指针不能是空指针.

由于实际解除引用指针是未定义的行为,是否有任何实现返回指向保护页面的指针?我想这很容易,并且有助于检测错误/提高安全性.

c++ new-operator

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

为什么分配成功为大小零字节?

这类似于零大小的数组分配/意味着什么?

我有以下代码

int *p = new int[0];
delete []p;
Run Code Online (Sandbox Code Playgroud)

p获取一个地址并被正确删除.

我的问题是:为什么c ++ Standard首先允许分配零字节?为什么不抛出bad_alloc或一些特殊的异常?

我认为,这只是推迟了灾难性的失败,使程序员的生活变得困难.因为如果要在运行时计算要分配的大小,并且如果程序员正确地假定其分配并尝试向该内存写入内容,则最终会破坏内存!并且崩溃可能发生在代码中的其他位置.

编辑:它在零大小请求时分配了多少内存?

c++ memory-management

6
推荐指数
3
解决办法
1934
查看次数

C++:内存泄漏

问题:变量n的值是多少,以下代码会导致内存泄漏?

那是代码:


int* Bar(int n)
{
  if (n == 1)
    throw "exception";
  return new int[n];
}

void Foo(int n)
{
  int *a = Bar(n);
  if (n <= 2)
    return;
  delete[] a;
}
Run Code Online (Sandbox Code Playgroud)

从5.3.4/7开始

当direct-new-declarator中的表达式的值为零时,将调用分配函数以分配不带元素的数组.

从3.7.3.1/2开始

取消引用作为零大小请求返回的指针的效果是未定义的.

即使[new]请求的空间大小为零,请求也会失败.

这意味着你可以做到,但你不能合法地(在所有平台上以明确定义的方式)取消引用你得到的内存 - 你只能将它传递给数组删除 - 你应该删除它.

这是一个有趣的脚注(即不是标准的规范部分,但包含在说明性的傀儡中)附在3.7.3.1/2的句子上

[32.目的是通过调用malloc()或calloc()来实现operator new(),因此规则基本相同.C++与C的不同之处在于要求零请求返回非空指针.

  • 如果n为1,我们得到:

int*a = Bar(1)和Bar(1)抛出异常.它是变量a的构造函数中的异常吗?它会导致内存泄漏吗?

c++ memory-leaks new-operator

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

什么是"new int [];" 做?

这行代码有什么作用?

new int[];
Run Code Online (Sandbox Code Playgroud)

根据我的编译器的反汇编(VC++ 2012),它的作用如下:

new int[0];
Run Code Online (Sandbox Code Playgroud)

但它是否由C++标准指定?这是法律指令吗?

c++ arrays new-operator c++11

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

重新初始化指针是不好的做法吗?

我有一个Image类,最初我不知道图像的尺寸,所以我只是将data_指针初始化为一个大小为0的数组.后来当我找到图像信息时,我重新初始化data_为一个新的大小.这会在内存中造成任何问题吗?有没有更清洁的方法来做到这一点?

以下是我写的课程:

class Image
{
private:
    int numRows_, numCols_;
    unsigned char* data_;
public:
    Image() : numRows_(0), numCols_(0), data_(new unsigned char[0])
    {}
    void setData(int r, int c, unsigned char* data)
    {
        this->numRows_ = r;
        this->numCols_ = c;
        this->data_ = new unsigned char[r*c];
        for (int i = 0; i < r*c; i++)
        {
            this->data_[i] = data[i];
        }
    }
    int rows();
    int cols();
    unsigned char* data();
    ~Image();
};
Run Code Online (Sandbox Code Playgroud)

提前致谢

c++

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