Что записано в памяти перед динамическим массивом?
for (int i=-4; i<=-1; i++)
cout << *(ptr_int + i) << " ";
40 - это размер массива в байтах в Windows.
А что означают остальные числа? Может это просто мусор и ничего не означают?
Поэтом формально, вы правы - там в первых 8-16 байтах не мусор! Он что-то значит для аллокатора, но с точки зрения языка С++ и программы на С++ эта информация - мусор. Является принципиальной ошибкой обращаться за пределы выделенного чанка. Кстати сборка в режиме отладким скорее всего должна выдать какие-нибудь ассерты при обращении таким образом.
Все сказанное относится к Linux. Что в Visual Studio сказать не могу, не уверен, что можно добыть исходники их C/C++ Library. В них наверняка содержится точный ответ.
Я много раз проверял для разных размеров массивов. И всегда в этом месте записывается число, которое показывает его размер. Т.е. по адресу ptr_int - 4.
40 = sizeof(int) * 10. Тут вроде бы все ясно)
40 = sizeof(int) * 10. Тут вроде бы все ясно)
угу. зависит от архитектуры. :)
а если так?
for (int i=-4; i<=-1; i++)
cout << (int)*(ptr_int + i) << " ";
-127 6 -37 0
"размер" куда вдруг подевался?
Никуда он не подевался )
for (int i=-4; i<=-1; i++)
cout << (int)*( (int *)ptr + i ) << " ";
Здесь опять видно что в 16 байт от начала массива находится его размер (имею ввиду что int занимает 4 байта)
И что интересно, все цифры те же самые. После размера массива идет единица (что она означает?), дальше 333 (что это число означает?)
Либо вам очень везет, либо у вас какой-то "чудесный" и "удивительный" аллокатор кучи используется.
Вообще-то ответ уже был дан сразу! Там должен быть мусор!
мне лень ставить студию и проверять на ней - но в любом случае - это мусор.
В указателе не хранится количество элементов массива (по крайней мере в С++), в указателе хранится адрес первого элемента.
using namespace std;
int main() {
cout << "First" << endl;
for (int size = 1; size <= 16; ++size) {
cout << " size = " << size << " : ";
int *ptr = new int[size];
for (int i=-4; i<=-1; i++)
cout << *( ptr + i ) << " ";
cout << endl;
}
cout << "Second" << endl;
for (int size = 1; size <= 16; ++size) {
cout << " size = " << size << " : ";
int *ptr = new int[size];
for (int i=-4; i<=-1; i++)
cout << *( ptr + i ) << " ";
cout << endl;
}
return 0;
}
size = 1 : 0 0 33 0
size = 2 : 0 0 33 0
size = 3 : 0 0 33 0
size = 4 : 0 0 33 0
size = 5 : 0 0 33 0
size = 6 : 0 0 33 0
size = 7 : 0 0 49 0
size = 8 : 0 0 49 0
size = 9 : 0 0 49 0
size = 10 : 0 0 49 0
size = 11 : 0 0 65 0
size = 12 : 0 0 65 0
size = 13 : 0 0 65 0
size = 14 : 0 0 65 0
size = 15 : 0 0 81 0
size = 16 : 0 0 81 0
Second
size = 1 : 0 0 33 0
size = 2 : 0 0 33 0
size = 3 : 0 0 33 0
size = 4 : 0 0 33 0
size = 5 : 0 0 33 0
size = 6 : 0 0 33 0
size = 7 : 0 0 49 0
size = 8 : 0 0 49 0
size = 9 : 0 0 49 0
size = 10 : 0 0 49 0
size = 11 : 0 0 65 0
size = 12 : 0 0 65 0
size = 13 : 0 0 65 0
size = 14 : 0 0 65 0
size = 15 : 0 0 81 0
size = 16 : 0 0 81 0
1) Соблюдается закономерность - числа зависят только от размера массива. Видимо третье число - размер выделенной памяти +1. Память похоже выделяется только кусками по 16 байт. Также можно предположить, что перед самим массивом имеется 8 (а не 4) байт с доп информацией.
2) Закономерность явно не такая, как написал deviser. Т.е это определенно зависит от компилятора.
P.S У меня ощущение, что сейчас половина форума дружно займется исследованиями мусора.
ну во первых точно неизвестно где будут записаны эти служебные данные слева или справа (точно может отличаться, но вот от чего зависит (OS, SW или HW) мне неизвестно)
во вторых то сколько выделено памяти под служебку также отличается (скорее всего из-за х32 и х64)
в третьих что 100% там лежит:
1.сколько байт занимает массив(скорее всего сколько там элементов), для операции deletе [ ]
2.тип хранимой информации, для dynamic_cast, то есть все типы нумеруются (какая то последовательность бит) и при dynamic_cast эти биты сравниваются
в четвёртых положение самих значений отличается у разных типов. например для
};
согласно всему вышеперечисленному как то работать с этой служебкой невозможно!!!! но именно с ней работает deletе [ ], dynamic_cast и typeid
p.s. когда-то очень сильно удивился так как максимальное число элементов в массиве new это 0х7fffffff (2 147 483 647)
--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
ответы на вопросы:
да,
более того как мне тут подсказали возможно и оба варианта сразу(но я не проверял, и сильно в этом сомневаюсь)
обычный двумерный массив записывается одной линией то есть а[5][5] будет занимать 5+5=10 и идти эти 10 будут подряд
но динамический а[5][5] должен выделиться в виде шести одномерных массивов по 5, один будет связывать адреса (это а[5]), а другой хранить значения (это а[#][5])
for (int i=1; i<=10; i++)
{
ptr = new int[i];
for (int j=-4; j<=-1; j++)
cout << (int)*((int *)ptr + j) << " ";
cout << endl;
}
8 1 733 -33686019
12 1 738 -33686019
16 1 743 -33686019
20 1 748 -33686019
24 1 753 -33686019
28 1 758 -33686019
32 1 763 -33686019
36 1 768 -33686019
40 1 773 -33686019
(Я тут столбики выровнил)
)
Первое число - это размер массива
Второе и четвертое вообще не меняются
А вот с третьим не совсем понятно. При увеличении размера массива это число тоже увеличивается.))
Только что заметил. Вообщем числа в третьем столбике увеличиваются на 5
Вы имеете ввиду перед массивом или после него?
char * b=(char*)a;
delete [] a;
а вот где она хранится (непосредственно перед массивом или гдето в специальном месте) зависит от компилятора
for (int i=1; i<=10; i++)
{
ptr = new int*[i];
for (int j=-4; j<=-1; j++)
cout << *(ptr + i) << " ";
cout << endl;
}
for (int i=1; i<=10; i++)
{
ptr = new int*[i];
for (int j=-4; j<=-1; j++)
cout << (int)*(ptr + j) << " ";
cout << endl;
}