删除[]和删除似乎行为相似

时间:2014-09-23 14:21:22

标签: c++

如果我使用deletedelete[],输出仍为70.我能知道原因吗?

#include<iostream>

using namespace std;

int main()
{
    int* c = new int[100];
    for(int i=0; i<98; i++)
    {
        c[i] = i;
    }

    cout<<c[70]<<endl;
    delete[] c;
      or
    delete c;
    cout<<c[70]<<endl; //outputs 70 even after delete[] or delete
    return 0;
}

3 个答案:

答案 0 :(得分:5)

访问已删除的内存是未定义的行为。使用错误的delete删除也是UB。任何进一步的讨论都是毫无意义的,因为你无法可靠地期望任何结果。

在许多情况下,UB只会执行“正确”的事情,但你需要知道这完全是“偶然”,并且可能会随着另一个编译器而改变,另一个版本相同编译器,天气...要获得正确的代码,您需要避免所有 UB的情况,即使那些看似有效的情况。

答案 1 :(得分:0)

其他人指出其未定义的行为,任何事情都可能发生。 借助valgrind等工具可以轻松捕获这些内容。

答案 2 :(得分:0)

使用new只会为程序分配一些内存并返回指向所述内存地址的指针,并保留数据类型所需的内存。当您稍后使用delete时,它会释放&#34;记忆,但不删除它的内容。如果你有一个int,其值70存储在该地址,它仍将包含70,直到另一个应用程序需要一些内存,获取所述地址并在其中放入另一个值。

如果使用new为数组分配内存,则会保留以下内存块,直到有足够的块用于指定的数组长度。

让我们说你做了以下事情:

int main() {
    int* array = new int[10]; // array now points to the first block of the allocated memory
    delete array;             // since array points to the first block of the array, it will only free that block, but nothing else, causing a memory leak
    delete[] array;           // will free all memory allocated by the previous new

    // Note that you should never free allocated memory twice, like in this code sample. Using delete on already freed memory is undefined behaviour!

]

始终对单个变量使用delete,对数组使用delete[]

演示您的问题:

int main() {
    int* c = new int[10];  // We allocate memory for an array of 10 ints
    c[0] = 1;              // We set the value of the first int inside the array to 1
    delete[] c;
    /* 
     * We free the previously allocated memory.
     * Note that this does not delete the CONTENT of the memory!
     * c does still point towards the first block of the array!
     */

    std::cout << c[0];
    /* 
     * Firstly, this is undefined behaviour (Accessing deallocated memory).
     * However, this will output 1,
     * unless some other process allocated the memory at the address
     * and filled it with another value already. (Very unlikely)
     */
    return 0;

}

如果要删除/覆盖已删除内存的内容,可以使用std::memset

示例:

#include <cstring>
int main() {
    std::size_t length = 10;
    int* c = new int[length];
    c[0] = 1;
    std::cout << c[0] << std::endl; // Will output 1
    std::memset( c, 0, length );    // Fill the memory with 0 bytes
    delete[] c;                     // Now we free the array's memory
    std::cout << c[0] << std::endl; // Will output 0
}