Почему malloc выделяет другое число байтов, чем требуемый?

Вы можете сделать левое соединение между двумя кадрами данных следующим образом:

import org.apache.spark.sql.functions.when
import spark.implicits._
val df1 = sc.parallelize(Seq((2,3),(1,4))).toDF("id1","id2")
val df2 = sc.parallelize(Seq((4,1),(2,3))).toDF("id1","id2")
val df3 = df1.join(df2, df1("id1")===df2("id1") && df1("id2") === df2("id2"), "left")
    .select(df1("id1"),
      df1("id2"),
      when(df2("id1").isNull, 0).otherwise(1).alias("label"))
df3.show()
+---+---+-----+
|id1|id2|label|
+---+---+-----+
|  2|  3|    1|
|  1|  4|    0|
+---+---+-----+

Надеюсь, это поможет вам.

7
задан Community 23 May 2017 в 11:54
поделиться

10 ответов

У Вас есть ошибка. Вместо:

translatedArray=malloc(4*sizeof(short int));

Вы должны иметь

translatedArray=malloc(4*sizeof(short int*));

Отметьте недостающий указатель в своем коде. Я подозреваю, что это - то, где Ваше наблюдаемое поведение происходит от.


Также заметьте это 0x804a420 - 0x804a018 = 1032, нет 516. Формула translatedArray[i] - translatedArray[i - 1] дает Вам число элементов (короткие целые, или проще, короткие замыкания) промежуточный два адреса, не число байтов.

9
ответ дан 6 December 2019 в 04:44
поделиться

Во-первых, Malloc не делает гарантий, что два последовательных вызова malloc возвращают последовательные указатели.

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

В-третьих, malloc нужны немного служебные, чтобы сохранить, насколько большой выделенный блок и т.д.

Не делайте предположения о том, какой malloc делает мимо, что говорит документация!

31
ответ дан 6 December 2019 в 04:44
поделиться

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

Кроме того, обычно malloc реализации будут вокруг требуемого размера до следующего несколько из 8 или 16 или некоторое другое кругловатое число.

Обновление: реальный ответ на Ваш вопрос заключается в Вашем использовании short int ввести. Когда выполнение адресной арифметики с указателями (вычитание) между введенными указателями, C и C++ возвращается, различие в количестве вещей указало. Так как Вы указываете short int, который составляет два байта в размере, возвращенное значение является половиной того, что Вы ожидаете.

С другой стороны, malloc всегда выделяет данное число байтов, к независимо от того, чему Вы бросаете результат позже. Попробуйте это:

    array=(short int*)malloc(sizeof(short int) * size);
17
ответ дан 6 December 2019 в 04:44
поделиться

Нет никаких гарантий что два блока возврата вызовов malloc, точно упакованные вместе - на самом деле нет никаких гарантий о результате вообще, за исключением того, что, если это не является ПУСТЫМ, он укажет на блок как наименьшее количество целый тот, который требуют.

Внутренне, большинство mallocs содержит рабочие данные, чтобы помочь им управлять "кучей". Например, те 8 байтов могли бы содержать два указателя - один указывающий на следующий блок, и один указывающий на предыдущий блок. Я не знаю то, что - те 8 байтов то, потому что Вы не упоминали, на котором ОС Вы работаете, но совершенно нормально для malloc использовать некоторую память для себя негласно.

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

12
ответ дан 6 December 2019 в 04:44
поделиться

Какие возвраты malloc зависит от реализации malloc и архитектуры. Как другие уже сказали, Вы, как гарантируют, получите, ПО КРАЙНЕЙ МЕРЕ, требуемый объем памяти или ПУСТОЙ УКАЗАТЕЛЬ. Это также, почему иногда, можно записать мимо конца массива и не получить отказ сегментации. Это - потому что у Вас на самом деле есть допустимый доступ к этой памяти, Вы просто не знали это.

5
ответ дан 6 December 2019 в 04:44
поделиться

malloc () обычно реализуется путем разделения доступной "кучи" в блоках различных размеров. В Вашем случае, malloc () возвращает 2 последовательных 1024 (или 16) блоки байта. 8 байтов пространства, которое Вы упоминаете, используются malloc () для бухгалтерской информации.

Посмотрите malloc Doug Lea () impl примечания здесь для понимания то, что входит негласно: http://g.oswego.edu/dl/html/malloc.html

4
ответ дан 6 December 2019 в 04:44
поделиться

malloc() будет иметь свои собственные издержки.

Не говоря уже о том, что нет никакой гарантии, что 2 последовательных выделения будут друг рядом с другом для начала.

3
ответ дан 6 December 2019 в 04:44
поделиться

Я нашел это ... и проверил ссылку ниже для получения дополнительной информации.

Распределение

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

required = требуемый + 8

при необходимости <= 16, тогда ведро = 0

При необходимости> 16, тогда bucket = (log (необходимо) / log (2) округлено до ближайшего целого числа) - 3

Размер каждого блока в списке, привязанного к сегменту, равен size block = 2 bucket + 4. Если список в bucket равен нулю, память выделяется с помощью подпрограммы sbrk для добавления блоков в список. Если размер блока меньше, чем страница, то страница выделяется с помощью подпрограммы sbrk, и число блоков, полученных путем деления размера блока на размер страницы, добавляется в список. Если размер блока равен или превышает страницу, необходимая память выделяется с помощью подпрограммы sbrk, и в свободный список для блока добавляется один блок. Если свободный список не пуст, блок в начале списка возвращается вызывающей стороне. Следующий блок в списке становится новым главой.

http://publib.boulder.ibm.com/infocenter/systems/index.jsp?topic=/com. ibm.aix.genprogc / doc / genprogc / sys_mem_alloc.htm

2
ответ дан 6 December 2019 в 04:44
поделиться

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

2
ответ дан 6 December 2019 в 04:44
поделиться

Прежде чем указатель стоит размер следующего массива, который является целым числом на 32/64 бита (не знайте, если подписано или неподписанный),

1
ответ дан 6 December 2019 в 04:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: