Странная ошибка sizeof () произошла на DevC ++ - PullRequest
2 голосов
/ 14 ноября 2011

Я знаю, что не должен использовать Dev-C ++, но это обязательно в школе, поэтому я ничего не могу с этим поделать.

Тема - указатели в C / C ++, и при измерении длины целочисленного массива произошла ошибка. Смотрите код ниже:

// POINTER
# include<iostream>
# include<string.h>

using namespace std;

int main(){
    //neues Feld anlegen
    int *a = new int[5];

    a[0] = 12;
    a[1] = 5;
    a[2] = 43;
    a[3] = -12;
    a[4] = 100;
    // Feld füllen

    for(int i = 0; i<sizeof(a);i++){
            cout<<a[i]<<"\n"<<endl;
            }
    cout<<sizeof(a);
    system("pause");
    return 0;

}

sizeof () возвращает 4, а не 5 ... Есть идеи?

Ответы [ 9 ]

26 голосов
/ 14 ноября 2011

Это не ошибка, потому что он возвращает размер самого a (который имеет тип int* - 4 байта в 32-битной сборке), а не длину массива.

Обратите внимание - другие говорят, что размер зависит от операционной системы, что наполовину верно. Это действительно зависит от сборки. sizeof является конструкцией времени компиляции.

5 голосов
/ 14 ноября 2011

Прежде всего, вы не должны думать, что виновником "странного" поведения является компилятор: большую часть времени ошибка ваша.

На самом деле, ваша инструкция sizeof говорит вам, каков размер int*, и это не так, так что это не ошибка компилятора, а ваше недопонимание. Нет способа использовать sizeof для определения размера динамически размещаемого массива.

2 голосов
/ 14 ноября 2011

a в этом случае - указатель, размер указателя зависит от компилятора.

Вы выполняете sizeof (int *).На самом деле вы используете 32-битный компилятор, а для вашего компилятора \ системные указатели 32-битные.

Вы не можете получить размер объекта, выделенного с новым из его указателя, sizeof оценивается во время компиляции, а невремя выполнения.

Чтобы получить размер массива, вы должны сделать ...

int a[5]; // Array allocated in stack, we can use sizeof.
std::cout << (sizeof(a) / sizeof(int));

sizeof возвращает размер в байтах, а не количество элементов в массиве.

Этот код эквивалентен записи

std::cout << (sizeof(int[5]) / sizeof(int));
1 голос
/ 14 ноября 2011

также заблуждение, что у вас здесь есть, что

int a* = new int[5];

означает, что вы объявляете указатель на массив типов int. На самом деле это не так.

int a* означает, что вы объявляете указатель на int.

new int[5] означает, что вы выделяете пространство памяти для 5 int типов.

int a* = new int[5]; означает, что вы выделяете память для хранения 5 дюймов и задаете для точки int точку a, указывающую на первый элемент.

Если вы объявили массив:

int a[5];  // an array of 5 ints

тогда вы могли бы:

for (int i=0; i< (sizeof(a)/sizeof(a[0])); i++)
{
  cout<<a[i]<<"\n"<<end1;
}  

cout<< sizeof(a)/sizeof(a[0]);
1 голос
/ 14 ноября 2011
int* a;
cout<<sizeof(a);

эквивалентно:

cout<<sizeof(int*);

Что является переменной величиной, в зависимости от платформы.На большинстве платформ x32 это будет 4 байта, а на платформах x64 - 8 байтов.

1 голос
/ 14 ноября 2011

Локальная переменная a - это тип указателя (int*).Размер указателя в 32-разрядных операционных системах составляет 4 байта.

1 голос
/ 14 ноября 2011

sizeof не говорит вам размер массива. Он сообщает вам размер типа данных, в данном случае int *, который на вашей платформе составляет 4 байта. Это всегда будет 4 независимо от количества элементов массива.

0 голосов
/ 14 ноября 2011

Вы просто получаете размер указателя , но не размер массива . Если вы скомпилируете этот код как 64-битный, вы получите другой результат.

Я обычно использую код ниже:

const int ARRAY_SIZE = 5;

int a* = new int[ARRAY_SIZE];
for (int i = 0; i < ARRAY_SIZE; ++i)
{
    // Do something.
}

// Release
if (a)
{
    delete[] a;
    a = NULL;
}
0 голосов
/ 14 ноября 2011

более простой способ сделать то, что вы хотите:

    #define NumberOfInts 5

    int* a = new int[NumberOFInts];

    for(int i = 0; i<NumberOfInts; i++){ 
    ....
    }    

Я не уверен, что это обычно считается "хорошим стилем", но это исправит ваш код.

...