相关疑难解决方法(0)

delete []如何知道它是一个数组?

好吧,我想我们都同意以下代码所发生的事情是未定义的,具体取决于传递的内容,

void deleteForMe(int* pointer)
{
     delete[] pointer;
}
Run Code Online (Sandbox Code Playgroud)

指针可以是各种不同的东西,因此delete[]对它执行无条件是未定义的.但是,让我们假设我们确实传递了一个数组指针,

int main()
{
     int* arr = new int[5];
     deleteForMe(arr);
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,在这种情况下,指针一个数组,谁知道这个?我的意思是,从语言/编译器的角度来看,它不知道arr数组指针是否指向单个int的指针.哎呀,它甚至不知道是否arr是动态创建的.但是,如果我做以下事情,

int main()
{
     int* num = new int(1);
     deleteForMe(num);
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

操作系统足够聪明,只能删除一个int,而不是通过删除超出该点的其余内存来进行某种类型的"杀戮狂欢"(与strlen\0终结字符串形成对比- 它将一直持续到它点击0).

那么他们的工作是记住这些东西吗?操作系统是否在后台保留某种类型的记录?(我的意思是,我意识到我开始这篇文章时说过发生的事情是未定义的,但事实是,'杀戮狂欢'的情况不会发生,所以因此在实际世界中有人记得.)

c++ arrays pointers new-operator delete-operator

135
推荐指数
7
解决办法
13万
查看次数

是否可以以便携方式使用新的数组放置?

在将它用于数组时,是否可以在便携式代码中实际使用新的放置?

看来你从new []返回的指针并不总是和你传入的地址相同(5.3.4,标准中的注释12似乎证实这是正确的),但是我不知道你是怎么回事如果是这种情况,可以为数组分配一个缓冲区.

以下示例显示了该问题.使用Visual Studio编译,此示例导致内存损坏:

#include <new>
#include <stdio.h>

class A
{
    public:

    A() : data(0) {}
    virtual ~A() {}
    int data;
};

int main()
{
    const int NUMELEMENTS=20;

    char *pBuffer = new char[NUMELEMENTS*sizeof(A)];
    A *pA = new(pBuffer) A[NUMELEMENTS];

    // With VC++, pA will be four bytes higher than pBuffer
    printf("Buffer address: %x, Array address: %x\n", pBuffer, pA);

    // Debug runtime will assert here due to heap corruption
    delete[] pBuffer;

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

查看内存,编译器似乎使用缓冲区的前四个字节来存储其中项目数的计数.这意味着因为缓冲区sizeof(A)*NUMELEMENTS很大,所以数组中的最后一个元素被写入未分配的堆中.

所以问题是你能找到你的实现需要多少额外的开销来安全地使用placement new []吗?理想情况下,我需要一种可在不同编译器之间移植的技术.请注意,至少在VC的情况下,不同类的开销似乎不同.例如,如果我删除示例中的虚拟析构函数,则new []返回的地址与我传入的地址相同.

c++ arrays compiler-construction portability overhead

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

分配2D数组的另一种方法?

我想使用malloc声明一个二维数组。在互联网上查找时,所有网站都告诉您声明一个int **指针,然后使用malloc首先将各个指针分配给1d数组,然后再次使用malloc为各个int分配空间。我的怀疑是,以这种方式声明的数组不会将其元素保存在连续的内存地址中。虽然以下方法仅使用一个malloc语句并动态分配2d数组,但所有地址均根据需要是连续的。因此,以下内容不是动态分配2d数组的正确方法吗?

#include <stdio.h>

int main(){
    int (*p)[2] = malloc(3 * sizeof *p);
    int i;
    int j;

        //All addresses printed here are contiguous
    for(i=0; i<3; i++){
        for(j=0; j<2; j++){
            printf("%d\t", &p[i][j]);
        }
        printf("\n");
    }
}
Run Code Online (Sandbox Code Playgroud)

c arrays malloc

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

使用重写的 new[] 运算符创建字符串数组

我们和我的朋友一起制作了一个带有覆盖 new 和 new[] 运算符的程序。我发现当我尝试使用以下代码创建字符串数组时:

string* Test1 = new string[10];
Run Code Online (Sandbox Code Playgroud)

函数返回无效指针(通常它的值向前移动 8 位,我正在将程序编译到 x64 平台)。我们的 new[] 函数看起来像这样:

void* operator new[] (size_t e)
{
    void* Test2 = operator new(e); 
    return Test2;
}
Run Code Online (Sandbox Code Playgroud)

在返回前用调试器运行程序时,指针的Test2值为 0x0000000009dfaa90,但值Test1变为 0x0000000009dfaa98。
这种情况只发生在字符串类型中。我试过对“int[10]”、“string* [10]”和我的一个类的对象做同样的事情,但只有在处理字符串时才会出现问题,还有代码:

string* Test1 = new string;
Run Code Online (Sandbox Code Playgroud)

工作得很好。

有人可以解释一下为什么会发生这种情况以及如何使其正常工作吗?

PS:我们使用的是 Visual Studio 2012 专业版

编辑:我刚刚测试了它未被覆盖,new[]并且在创建字符串表时它的工作方式相同(返回的指针不是函数尝试的指针return),所以它似乎不是问题。有人能解释一下为什么指针的值只对字符串数组改变,如果似乎没有任何其他指令可以改变它,它会如何改变?

c++ string overriding new-operator

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

为什么“new”的不同使用方式会导致结果与“delete”不兼容?

我正在阅读有关内存的 C++ Primer Plus, 12.1.3,以及有关析构函数的一些内容真的让我感到困惑。

//Here is a default construtor of String class
String::String()
{
   len = 0;
   str = new char[1];
   str[0] = '\0';
}
Run Code Online (Sandbox Code Playgroud)

书上说,使用str = new char[1]not str = new char,两种方式分配相同的内存,但第二种与析构函数不兼容。此外,书中说以下3种方式不好,因为它们与“删除”不兼容

char words[15] = "bad idea";
char *p1 = words;
char *p2 = new char;
char *p3;
delete [] p1; //undefined, so don't do it
delete [] p2; //undefined, so don't do it
delete [] p3; //undefined, so don't do it
Run Code Online (Sandbox Code Playgroud)

我不知道这 3 种方式有什么不同,有人可以向我解释一下吗?非常感谢。

c++ pointers destructor class

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