C/C++

Почему Visual studio выдаёт ошибку работы с памятью, если она была выделена calloc-ом?

Size_t i, j;
for (i = 0; i < count; i++)
for (j = (i % 2) ? 0 : 1; j + 1 < count; j += 2)
if (arr[j].count > arr[j + 1].count)
{
DETAIL buffer;
buffer = arr[j];
arr[j] = arr [j + 1];
arr[j + 1] = buffer;
}
Calloc выделяет не виртуальную адресную, а физическую (реальную) память с доступных страниц памяти.
Много этой памяти взять нельзя. Будет превышение и выход за границы, например, стека, и крах программы.

Лучше использовать malloc, который хоть и медленней, но может черпать, по сути, всю оперативную память. Можно взять памяти максимально. И меньше вероятность краха программы потому, что редко при этом используется сразу все ОЗУ компа.
Игорь Ямашкин
Игорь Ямашкин
37 945
Лучший ответ
Владимир Звездин Откуда ты это взял (про виртуальную память)? На Windows это 100% чепуха. Подозреваю, что на Unix тоже.
В C существует строгое требование, память должна освобождаться в той же функции, в которой был объявлен указатель, по которому она выделялась. Поэтому, объявить указатель и выделить под него память в одной функции, как это сделано у вас, и передать его в другую через возвращаемое значение не получится, равно как и вернуть через выходной параметр. Поэтому в функцию передаётся указатель как аргумент и этот же указатель следует вернуть как возвращаемое значение.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int* create(int* ptr, size_t len) {
size_t i, n;
ptr = calloc(len, sizeof(int));
for (i = 0; i < len; ++i) ptr[i] = 10 + rand() % 90;
return ptr;
}
int main(void) {
int* ptr = NULL;
size_t len;
size_t i;
srand((unsigned)time(NULL));
len = 1 + rand() % 25;
ptr = create(ptr, len);
for (i = 0; i < len; ++i) printf("%4i", ptr[i]);
puts("");
free(ptr);
return 0;
}
По этому коду непонятно. Может память не выделена, или выделена, но мало. Или сначала выделена, потом освобождена. Куча вариантов.
Что правильно написано, то правильно работает.
Андрей Аминов Массив создаётся этой функцией

DETAIL* generate(size_t count)
{
DETAIL* result; /*Указатель на начало массива.*/
count = (size_t)rand(); /*Считываем размер массива.*/
if (result = (DETAIL*)calloc(count, sizeof(DETAIL)))
{/*Если удалось выделить память...*/
size_t i; /*Параметр цикла.*/
for (i = 0; i < count; i++) /*Считываем массив.*/
result[i].count = (unsigned)rand(),
result[i].name = 0;

}
return result;
}