C + + динамічно виділений 2D масив totalocate пам'яті?

Я почав вивчати C ++, і хотів реалізувати простий 2D масив і отримати його розмір, не використовуючи std :: vector . Однак я стикаюся з дивними помилками з моїм другим виміром:

int **data= new int*[2];
for (int i = 0; i<2;i++){
    data[i] = new int[3];
}

data[0][0] = 1;
data[0][1] = 2;
data[0][2] = 3;

data[1][0] = 4;
data[1][1] = 5;
data[1][2] = 6;

data[1][25] = 20; //Should segfault? AAAAA

cout << "Data[1][25] = " << data[1][25] << endl; //Should segfault, no?

int n = sizeof(data[0])/sizeof(int);
int m = sizeof(data)/sizeof(int);
cout << "M is " << m << " N is " << n << endl;// Reports m = 2, n =2?!?!? BBBB

У AAAA я повинен отримувати segfault, ні? Замість цього я можу присвоїти значення, а потім прочитати його. Значення data [1] [any] дорівнює нулю, як і було ініціалізовано. Це лише проблема в другому вимірі, перше вимірювання веде себе так, як очікувалося.

Пізніше BBBB я не отримую точний розмір для n . Я робити щось не так?

0

15 Відповіді

C ++ не виконує обов'язкову перевірку масивів. Доступ до даних за межі масиву - це невизначена поведінка, і все може статися. Він може викликати segfault це може не. Якщо у вас є дійсні області пам'яті до або після масиву, ви можете в кінцевому підсумку отримати або змінити цю пам'ять. Це може призвести до корупції інших даних, які використовуються вашою програмою.

Також ви неправильно використовуєте sizeof . sizeof - це конструкція часу компіляції . Він не може використовуватися для визначення розміру масиву за допомогою значення покажчика під час виконання. Якщо вам потрібна така функціональність, скористайтеся командою std :: array або std :: vector .

char somearray[10];
int size = sizeof(somearray);//result is 10. Yay it works.

char *somearrayptr = new char[10];
int size = sizeof(somearrayptr); //size = the size of char* not char[10].
3
додано

C ++ не виконує обов'язкову перевірку масивів. Доступ до даних за межі масиву - це невизначена поведінка, і все може статися. Він може викликати segfault це може не. Якщо у вас є дійсні області пам'яті до або після масиву, ви можете в кінцевому підсумку отримати або змінити цю пам'ять. Це може призвести до корупції інших даних, які використовуються вашою програмою.

Також ви неправильно використовуєте sizeof . sizeof - це конструкція часу компіляції . Він не може використовуватися для визначення розміру масиву за допомогою значення покажчика під час виконання. Якщо вам потрібна така функціональність, скористайтеся командою std :: array або std :: vector .

char somearray[10];
int size = sizeof(somearray);//result is 10. Yay it works.

char *somearrayptr = new char[10];
int size = sizeof(somearrayptr); //size = the size of char* not char[10].
3
додано

C ++ не виконує обов'язкову перевірку масивів. Доступ до даних за межі масиву - це невизначена поведінка, і все може статися. Він може викликати segfault це може не. Якщо у вас є дійсні області пам'яті до або після масиву, ви можете в кінцевому підсумку отримати або змінити цю пам'ять. Це може призвести до корупції інших даних, які використовуються вашою програмою.

Також ви неправильно використовуєте sizeof . sizeof - це конструкція часу компіляції . Він не може використовуватися для визначення розміру масиву за допомогою значення покажчика під час виконання. Якщо вам потрібна така функціональність, скористайтеся командою std :: array або std :: vector .

char somearray[10];
int size = sizeof(somearray);//result is 10. Yay it works.

char *somearrayptr = new char[10];
int size = sizeof(somearrayptr); //size = the size of char* not char[10].
3
додано

C ++ не виконує обов'язкову перевірку масивів. Доступ до даних за межі масиву - це невизначена поведінка, і все може статися. Він може викликати segfault це може не. Якщо у вас є дійсні області пам'яті до або після масиву, ви можете в кінцевому підсумку отримати або змінити цю пам'ять. Це може призвести до корупції інших даних, які використовуються вашою програмою.

Також ви неправильно використовуєте sizeof . sizeof - це конструкція часу компіляції . Він не може використовуватися для визначення розміру масиву за допомогою значення покажчика під час виконання. Якщо вам потрібна така функціональність, скористайтеся командою std :: array або std :: vector .

char somearray[10];
int size = sizeof(somearray);//result is 10. Yay it works.

char *somearrayptr = new char[10];
int size = sizeof(somearrayptr); //size = the size of char* not char[10].
3
додано

У AAAA у вас є невизначена поведінка. З цього моменту може статися щось, і ще цікавіше, навіть раніше.

У стандартній C ++ така поведінка не існує як "segfault". І здійснення може визначити деякі операції, щоб зробити це, але я не знаю, якщо хтось колись турбувався. Це буває випадково для деяких випадків.

2
додано

У AAAA у вас є невизначена поведінка. З цього моменту може статися щось, і ще цікавіше, навіть раніше.

У стандартній C ++ така поведінка не існує як "segfault". І здійснення може визначити деякі операції, щоб зробити це, але я не знаю, якщо хтось колись турбувався. Це буває випадково для деяких випадків.

2
додано
data[1][25] = 20; //Should segfault? AAAAA

Це буде сегментарно, якщо вам не дозволено отримати доступ до місця розташування. У C ++ немає перевірки, щоб перевірити, чи є місце, до якого ви звертаєтесь, дійсно з кодове точки зору .

Ви отримали вихід, тому що він був збережений у цьому місці. Це могло бути що завгодно. Це невизначена поведінка, і ви не можете отримати однаковий результат кожного разу.

Див. цю відповідь, хоча йдеться про абпут локальні змінні, але це дає хороші приклади того, як такий доступ до даних може бути невизначеною поведінкою

data and data[0] are both pointers (doesn't matter single or double). They have a defined size for every implementation. In your case, size of pointer is twice that of size of int on your machine. Hence, the output. sizeof when used with pointers pointing to arrays (and not arrays i.e. ones declared as arrays char a[] etc) gives the size of the pointer

1
додано
data[1][25] = 20; //Should segfault? AAAAA

Це буде сегментарно, якщо вам не дозволено отримати доступ до місця розташування. У C ++ немає перевірки, щоб перевірити, чи є місце, до якого ви звертаєтесь, дійсно з кодове точки зору .

Ви отримали вихід, тому що він був збережений у цьому місці. Це могло бути що завгодно. Це невизначена поведінка, і ви не можете отримати однаковий результат кожного разу.

Див. цю відповідь, хоча йдеться про абпут локальні змінні, але це дає хороші приклади того, як такий доступ до даних може бути невизначеною поведінкою

data and data[0] are both pointers (doesn't matter single or double). They have a defined size for every implementation. In your case, size of pointer is twice that of size of int on your machine. Hence, the output. sizeof when used with pointers pointing to arrays (and not arrays i.e. ones declared as arrays char a[] etc) gives the size of the pointer

1
додано
data[1][25] = 20; //Should segfault? AAAAA

Це буде сегментарно, якщо вам не дозволено отримати доступ до місця розташування. У C ++ немає перевірки, щоб перевірити, чи є місце, до якого ви звертаєтесь, дійсно з кодове точки зору .

Ви отримали вихід, тому що він був збережений у цьому місці. Це могло бути що завгодно. Це невизначена поведінка, і ви не можете отримати однаковий результат кожного разу.

Див. цю відповідь, хоча йдеться про абпут локальні змінні, але це дає хороші приклади того, як такий доступ до даних може бути невизначеною поведінкою

data and data[0] are both pointers (doesn't matter single or double). They have a defined size for every implementation. In your case, size of pointer is twice that of size of int on your machine. Hence, the output. sizeof when used with pointers pointing to arrays (and not arrays i.e. ones declared as arrays char a[] etc) gives the size of the pointer

1
додано

Доступ до масиву за межами його кордонів - це невизначена поведінка . Отже, немає ніяких підстав чекати, що щось зокрема станеться: це може спричинити крах, повернути правильну відповідь, повернути неправильну відповідь, тихо пошкодити дані в іншій частині програми або цілий ряд інших можливостей.

1
додано

Доступ до масиву за межами його кордонів - це невизначена поведінка . Отже, немає ніяких підстав чекати, що щось зокрема станеться: це може спричинити крах, повернути правильну відповідь, повернути неправильну відповідь, тихо пошкодити дані в іншій частині програми або цілий ряд інших можливостей.

1
додано

Доступ до масиву за межами його кордонів - це невизначена поведінка . Отже, немає ніяких підстав чекати, що щось зокрема станеться: це може спричинити крах, повернути правильну відповідь, повернути неправильну відповідь, тихо пошкодити дані в іншій частині програми або цілий ряд інших можливостей.

1
додано

Обидва дані [0] та дані - покажчики. Покажчики будуть розміром 4 на 32-бітній системі, а 8 - на 64-розрядній системі. Тому m та n рівні. Розмір int завжди 4.

0
додано

Обидва дані [0] та дані - покажчики. Покажчики будуть розміром 4 на 32-бітній системі, а 8 - на 64-розрядній системі. Тому m та n рівні. Розмір int завжди 4.

0
додано

Обидва дані [0] та дані - покажчики. Покажчики будуть розміром 4 на 32-бітній системі, а 8 - на 64-розрядній системі. Тому m та n рівні. Розмір int завжди 4.

0
додано
IT KPI C/С++ новым годом
IT KPI C/С++ новым годом
747 учасників

Чат обсуждения С/С++. - Вопросы "напишите за меня лабу" - это оффтоп. - Оффтоп, флуд, оскорбления и вбросы здесь не приняты. - За нарушение - предупреждение или mute на неделю. - За спам и рекламу - ban. Все чаты IT KPI: https://t.me/itkpi/1147