Неожиданный размер при использовании mallo c () - PullRequest
0 голосов
/ 10 февраля 2020

Я хотел проверить свои знания и написал небольшую программу, которая выглядит следующим образом:

#include <iostream>
#include <cstdlib>

int main()
{
    int* mem1 = (int*) malloc(2 * sizeof(int));
    int* mem2 = (int*) malloc(5 * sizeof(int));

    std::cout << "mem1: " << sizeof(mem1) << std::endl;
    std::cout << "mem2: " << sizeof(mem2) << std::endl;

    return 0;
}

Я получаю вывод:

mem1: 8
mem2: 8

Когда я изменяю значения, что malloc(2 * sizeof(int)) до malloc(3 * sizeof(int)), вывод также не меняется.

Этот - это Учебное пособие, которое я использовал, поэтому я не совсем уверен, безопасно ли это для памяти, с преобразование в int* при звонке malloc. Я также нашел этот вопрос, но я не считаю его очень полезным в моем случае. Clang ++ - это компилятор, который я использовал, но я не думаю, что это имеет какое-либо значение.

Мое лучшее предположение, что он выделяет ту же память, потому что он не знает, где заканчивается память.

Ответы [ 4 ]

1 голос
/ 10 февраля 2020

sizeof сообщает вам размер компиляции указателя (он сообщал бы об одном и том же значении, даже если вы вообще никогда не вызывали malloc). Не существует совместимого со стандартами способа определения объема памяти, выделенного malloc; вы должны хранить его в боковом диапазоне, если вам нужно сохранить эту информацию.

0 голосов
/ 10 февраля 2020

Как упоминалось выше, в этом вопросе есть несколько проблем:

  1. В C ++ вы динамически распределяете память, используя оператор new . Опция использования mallo c предназначена для работы с API-стилями c, когда необходимы динамические c выделения, которые будут отменены функцией c -free. Чтобы сделать такое распределение, лучше всего использовать std :: mallo c, о котором вы можете прочитать в этой ссылке (cpp ссылка) .
  2. Оператор sizeof вычисляет размер типа stati c , что означает, что он возвращает вам размер целочисленного указателя, который является постоянным, в зависимости от архитектуры вашего процессора.
  3. Работа с Необработанные указатели в C ++ не рекомендуется, вы всегда должны убедиться, что для каждого элемента, динамически создаваемого в памяти, существует владелец , который отвечает за его удаление, когда он больше не нужен. В C ++ 11 и более поздних версиях это может быть достигнуто с помощью интеллектуальных указателей , таких как std :: unique_ptr. Фактически, C ++ создал замечательную идиому для управления ресурсами, названную RAII ( Resource Allocation Is Initialization ), которая отличает его от многих других языков.
0 голосов
/ 10 февраля 2020

Выражение sizeof(mem1) будет всегда возвращать одно и то же значение, независимо от размера выделенного блока памяти! Это связано с тем, что mem1 является указателем на выделенную память, а размер указателя не изменяется (то есть в данной среде).

В вашем случае (предположительно) (сборка на 64-битной платформе) указатели имеют длину 8 байт. Вы можете построить это для другой платформы (скажем, для 32-битной системы), и вы можете получить другой размер (например, 4); но на этой платформе этот размер будет всегда равным 4.

0 голосов
/ 10 февраля 2020

8 байтов, которые вы видите, является размером указателя (int*). sizeof () выполняется во время компиляции, и компилятор не может узнать этот размер во время компиляции (malloc - это динамическое c выделение памяти).

...