这是我一直想知道的事情,从来没有找到答案:
为什么当你在堆上分配一些东西时,你无法仅通过指针来确定它的大小,但是你可以仅使用指针来删除它,不知何故C++知道要释放多少字节?
这与它在堆上的存储方式有关吗?这些信息是否存在但C++没有公开?
也许这应该是一个单独的问题,但我认为它非常相关所以我会在这里问:
为什么必须使用delete []简单的delete命令来删除动态的元素数组; 为什么C++需要这些额外的信息才能正确释放所有内存?
删除操作符如何工作?它比free()更好吗?如果你这样做ptr=new char[10],那么删除使用delete ptr,指针如何知道要删除多少个位置.
我今天正在阅读有关delete和delete[]运算符的内容,我可以看到,为了释放分配的内存myChar,我应该调用delete并释放内存,因为myCharArray我应该使用delete[].
但是我一直认为它myChar是一个指向大小为1的数组的指针.那么为什么我们delete在这种情况下使用它呢?为什么我们需要delete呢?delete[]如果myChar实际上是一个大小为1的数组,我们难道不能在任何地方使用吗?
char* myChar = new char;
char* myCharArray = new char[5];
delete myChar;
delete[] myCharArray;
Run Code Online (Sandbox Code Playgroud) 我是C++的新手,我有一些不清楚的地方:
#include <iostream>
using namespace std;
double* foo(void)
{
double* b = new double[100];
return b;
}
int main()
{
double* a = foo();
delete [] a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这段代码有问题吗?我的意思是我使用operator delete的方式是否正确?我指向foo函数中指向已分配内存的指针b指向外部foo,我可以通过delete [] a释放内存吗?我不知道编译器如何计算执行delete []时要释放的字节数.谢谢
我尝试了一些有趣的代码(至少对我而言!).这里是.
#include <iostream>
struct myStruct{
int one;
/*Destructor: Program crashes if the below code uncommented*/
/*
~myStruct(){
std::cout<<"des\n";
}
*/
};
struct finalStruct {
int noOfChars;
int noOfStructs;
union {
myStruct *structPtr;
char *charPtr;
}U;
};
int main(){
finalStruct obj;
obj.noOfChars = 2;
obj.noOfStructs = 1;
int bytesToAllocate = sizeof(char)*obj.noOfChars
+ sizeof(myStruct)*obj.noOfStructs;
obj.U.charPtr = new char[bytesToAllocate];
/*Now both the pointers charPtr and structPtr points to same location*/
delete []obj.U.structPtr;
}
Run Code Online (Sandbox Code Playgroud)
我已将内存分配给charPtr并使用structPtr删除.当我向myStruct添加析构函数时崩溃,否则没有问题.
这到底发生了什么.据我所知,delete []将调用析构函数的次数与new []中给出的次数相同.为什么在myStruct中没有析构函数时它不会崩溃?
在"The C++ Programming Language"一书中,Stroustrup说:
"要释放由new分配的空间,删除和删除[]必须能够确定分配的对象的大小.这意味着使用new的标准实现分配的对象将占用比静态对象稍多的空间.通常,一个word用于保存对象的大小.
这意味着分配的每个对象new的大小都位于堆中的某个位置.位置是否已知,是否可以访问它?
假设我们有以下课程
class Data
{
public:
Data() : i(new int) { *i = 0; }
~Data() { delete i; }
private:
int *i;
};
Run Code Online (Sandbox Code Playgroud)
现在我们创建100个Data类型元素的数组
Data* dataArray = new Data[100];
Run Code Online (Sandbox Code Playgroud)
我们知道operator new会为100个对象调用Data构造函数,因为它知道创建了多少个对象,现在让我们删除这个数组,如果我们说delete dataArray只调用第一个对象的析构函数,即使我们知道100个对象的内存我们被释放 - 将导致内存泄漏 - 并且因为它们被分配为一个块,但是如果我们说delete[] dataArray将调用100个对象的析构函数,但这是一个dynmaic内存并且我没有指定那里有多少个对象我知道数组没有任何开销来知道其中有多少对象,那么运行时环境如何知道在释放内存之前要销毁的对象数量?
根据这个问题的答案:" delete [] " 如何知道"操作数数组的大小? "
你的分配器将跟踪你分配的内存量
和
多么自由地知道释放多少内存"
是的,内存块大小由malloc存储在"某处"(通常在块本身中),这就是免费知道的.但是,new []/delete []是一个不同的故事.后者基本上在malloc/free之上工作.new []还存储它在内存块中创建的元素数量(独立于malloc),以便后来delete []可以检索并使用该数字来调用适当数量的析构函数
这是否意味着delete []与指针指向的位置无关?以下代码是否有效或是否会导致内存泄漏?
void createArray(){
char* someArray = new char[20];
readData(someArray);
//Is this delete still valid after moving the pointer one position?
delete[] someArray;
}
char readData(char* &arr){
char value = *arr;
//Let it point to the next element
arr += 1;
return value;
}
Run Code Online (Sandbox Code Playgroud) 我知道你必须这样做:
int * p;
p = new int[10];
//use array
delete [] p;
Run Code Online (Sandbox Code Playgroud)
现在我的问题是:由于没有明确说明,如何释放正确的内存量?操作系统是否跟踪分配的内存及其起始地址?
这个问题困扰了我一段时间.
int* a = new int[n]例如,如果我这样做,我只有一个指向数组a开头的指针,但C/C++是如何知道的n?我知道如果我想将这个数组传递给另一个函数,那么我必须用它传递数组的长度,所以我猜C/C++并不知道这个数组有多长.
我知道我们可以char*通过查找NUL终结符来推断字符数组的结尾.但其他数组是否有类似的机制,比如int?同时,char可以不仅仅是一个字符 - 您也可以将其视为整数类型.那么C++如何知道这个数组的结束呢?
当我开发嵌入式Python时,这个问题开始让我更加困扰(如果你不熟悉嵌入式python,你可以忽略这个段落并回答上面的问题.我仍然会欣赏它).在Python中有一个"ByteArray",将这个"ByteArray"转换为C/C++的唯一方法是使用PyString_AsString()将其转换为char*.但是如果这个ByteArray中有0,那么C/C++会认为char*数组会提前停止.这不是最糟糕的部分.最糟糕的是,比方说我做了
char* arr = PyString_AsString(something)
void* pt = calloc(1, 1000);
Run Code Online (Sandbox Code Playgroud)
如果st恰好从0开始,那么C/C++几乎可以保证消灭arr中的所有内容,因为它认为arr在出现NULL之后就会结束.然后它可能只是通过为pt分配一个内存树干来消灭arr中的所有内容.
非常感谢您的宝贵时间!对此,我真的非常感激.
我知道我应该使用std::vector或其他替代方案,但有一些我不明白的指针.
当我们创建一个指针数组时:
int* a = new int[100];
Run Code Online (Sandbox Code Playgroud)
它应该分配一个空间100 * sizeof(int),不是吗?
当我们不再需要它时,我们会这样做:
delete [] a;
Run Code Online (Sandbox Code Playgroud)
1.
这是错的:
delete a;
Run Code Online (Sandbox Code Playgroud)
但是,当我实际执行此操作时(偶然在休闲程序中执行此操作),似乎不会触发运行时错误(下面第3部分中的unllike)并且程序正常运行(尽管可能存在内存泄漏).为什么?它是否真的删除(释放)了数组的第一个元素?
2.
根据StackOverflow上的一个问题,delete[]知道它需要删除的数组的大小.
但是当我删除错误的东西时会发生什么?(它导致运行时错误...在它显示的codepad.org上memory clobbered before allocated block以及Debug Assertion FailedVS2010中的内容.)为什么不删除(免费)元素1到99?
delete [] &a[1]; // or
delete [] (a + 1);
Run Code Online (Sandbox Code Playgroud)
3.
以下代码也显示memory clobbered before allocated block.但为什么不删除(免费)元素99?为什么它会导致错误,但delete a就像第1部分中那样?
delete &a[99]; //or
delete (a + 99);
Run Code Online (Sandbox Code Playgroud)
C++标准是否真的说明了上述内容会发生什么?
int* i = new int[4];
delete[] i;
Run Code Online (Sandbox Code Playgroud)
正如HadeS所说,它将保存已分配多少内存的信息?在哪里?它必须保存在内存中,或者可能在指针附近i.