C/C++

Помогите, понять почему выдает run-time error

 #define _CRT_SECURE_NO_WARNINGS  
#include
#include
#include
#define N 100001





int comp(const void *i, const void *j)
{
if (*(long long *)i - *(long long *)j < 0)
return -1;
else
{
if (*(long long *)i - *(long long *)j > 0)
return 1;
else
return 0;
}

}

int compstr(const void *i, const void *j)
{
return strcmp(*(char**)i, *(char**)j);
}

int lowerBound(const void * searchkey, const void * baseptr, size_t number, size_t size, int(*funccompar) (const void *, const void *))
{
if (size == sizeof(int))
{
for (int i = 0; i < number; ++i)
{
long long x = ((long long*)baseptr)[i];
if (funccompar(searchkey, &x)
Данная программа может выдавать ошибку времени выполнения, если количество элементов в массиве b (строк) превышает N, то есть 100001.

В строке кода:

char** b=(char**)malloc(N);

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

Для решения этой проблемы можно использовать динамическое выделение памяти под каждую строку отдельно, в цикле, при чтении входных данных. Также, можно использовать специальные функции для чтения строк из файла, например fgets.

Пример исправления данной проблемы:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
const int N = 100001;

FILE* in = fopen("input.txt", "r");
FILE* out = fopen("output.txt", "w");

long long a[N];
char** b = (char**)malloc(N * sizeof(char*));

int n1, n2, n3, n4;
long long x;
char p[32];

fscanf(in, "%d\n", &n1);
for (int i = 0; i < n1; ++i)
fscanf(in, "%lld\n", &a[i]);

qsort(a, n1, sizeof(long long), comp);

fscanf(in, "%d\n", &n2);
for (int i = 0; i < n2; ++i)
{
fgets(p, 32, in);
int len = strlen(p);
if (p[len-1] == '\n') p[len-1] = '\0'; // удаляем символ переноса строки
b[i] = (char*)malloc(len);
strcpy(b[i], p);
}

qsort(b, n2, sizeof(char*), compstr);

fscanf(in, "%d\n", &n3);
for (int i = 0; i < n3; ++i)
{
fscanf(in, "%lld\n", &x);
fprintf(out, "%d\n", lowerBound(&x, a, n1, sizeof(long long), comp));
}

fscanf(in, "%d\n", &n4);
for (int i = 0; i < n4; ++i)
{
fgets(p, 32, in);
int len = strlen(p);
if (p[len-1] == '\n') p[len-1] = '\0'; // удаляем символ переноса строки
fprintf(out, "%d\n", lowerBound(&p, b, n2, sizeof(char*), compstr));
}

fclose(in);
fclose(out);

for (int i = 0; i < n2; ++i) // освобождаем память под каждую строку
Евгений Карасев
Евгений Карасев
11 256
Лучший ответ
Если файл не найден (а у вас нет проверки на успешность открытия файла) то будет ошибка.
Поместите файл input.txt в какое нибудь простое место и в пишите полный путь к нему.
Например на диск D
и тогда полный путь будет:
 FILE* in = fopen("D:/input.txt", "r"); 
FILE* out = fopen("D:/output.txt", "w");
Можете написать проверку после этого:

 if (in == NULL) {printf ("%s", "Cant't open file D:/input.txt"); exit(0);}