Имеет значение для free() и delete [], если выделение было выполнено в стеке или куче?

Free() знает, сколько байт памяти освободится, но может удалить [] сделать то же самое? Что, если мы выделяем из стека вместо кучи, они работают безупречно со свободными() и delete []? Последний вопрос: нам нужно назначить NULL в конце?

#include <stdio.h>
#include <stdlib.h>

char * malloc2()
{
 char * m = (char *)malloc(100);
 //so malloc(10000000) cannot cause stack-overflow?
 //cast from void * to char *
 return m;
}

char * malloc3()
{
 static char m[100];
 //can [1000000] cause stack overflow?
 return m;
}

char * newX()
{
 char * output = new char[100];
 return output;
}

int main(){

 char * p = malloc2();
 //sizeof(p) gives 8 because this is on 64 bit OS/CPU
 free(p);
 //free() knows the size of p is 100.
 //Does it matter if this allocation from stack of malloc2()?
 p=NULL;

 char * q = malloc3();
 //again, sizeof(q) fives 8
 //is this allocation from stack of malloc3()?
 //I dont need to free because that was from an array declaration ?
 q=NULL;
 //then who deletes that static array from the stack?


 char * r = malloc3();
 //now r and q point to same memory area ? 
 // then if I free q, I dont need to free r.
 r=NULL;

 char * s = newX();
 //allocation from stack again?
 //sizeof(s) gives 8, how can delete[] know its size?
 delete [] s;
 s=NULL;

 return 0;
}
</stdlib.h></stdio.h>

Спасибо.

3 ответа

Ни free ни delete ни delete [] работают с выделенной памятью.

Правило на самом деле смехотворно просто:

  • Каждый malloc должен быть соединен с одним free, и наоборот. 1
  • Каждое new должно быть сопряжено с одним delete, и наоборот.
  • Каждый new [] должен быть сопряжен с одним delete [] и наоборот.

Конец.

+1 Ладно, я солгал. malloc/free сложнее, потому что theres также calloc и realloc. Имеет измененное правило:

  • Каждый malloc или calloc должен быть сопряжен с одним вызовом для free или realloc.
  • Каждый realloc, который не освобождает память, должен быть сопряжен с одним вызовом free или realloc.
  • (И наоборот: каждый free должен принадлежать только одному вызову, сделанному в malloc, calloc или realloc.)

Другими словами, calloc ведет себя как malloc (ради распределения памяти). realloc является инклюзивным промежуточным звеном mallocfree chain - он может заменить как malloc и free, и он может быть вставлен между такими вызовами.


Чтобы ответить на последний вопрос: сохранение NULL в переменной указателя требуется только в том случае, если ваш проект требует его; он указывал, что указатель не указывает на что-либо. Делать это здесь просто пустая трата времени, потому что p уходит в конце функции:

void f() {
 char *p = new char[10];
 delete [] p;
 p = NULL;
}


Вы никогда не должны освобождать или удалять сложную переменную. Они будут автоматически уничтожены при возврате их кадров стека. Вы можете удалить только те объекты, которые были выделены для новых и только бесплатных() вещей, выделенных семейством malloc().

licensed under cc by-sa 3.0 with attribution.