Вызвано исключение по адресу 0x00007FFBDC966654 : 0xC0000005: нарушение прав доступа при чтении по адресу 0xFFFFFFFFFFFFFFFF
пишет данную ошибку в данном фрагменте кода
int MassA(struct EL_SP* p, char* arr[255])
{
int k = 0;
printf("\nВведите число К:\n");
scanf_s("%d", &k);
printf("\nМассив A:\n");
struct EL_SP* h;
for (h = p; h != NULL; h = h->sled)
{
if (k < 255) {
strcpy_s(arr[k++], MAXDL, h->id);
}
else {
printf("Массив A заполнен полностью.\n");
break;
}
}
return k;
}
Не могу понять в чем ошибка, также ниже указал полный код.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <locale.h>
#define MAXDL 9
/* макс.длина ид-ра (строки символов с признаком конца '\0' ) */
struct EL_SP /* тип элемента списка */
{
char id[MAXDL]; /* идентификатор */
struct EL_SP* sled; /* ссылка на следующий элемент */
};
void Vkl(struct EL_SP** p, char t_id[])
/* Вх. данные: *p - указатель списка идентификаторов в
лексикографическом порядке,
t_id - включаемый в список (текущий) ид-р */
/* Вых. данные: *p */
{
struct EL_SP* pt, /* указатель включаемого эл-та */
* k, * j; /* указатели очередного и предыдущего
элементов списка */
/* выделение памяти для нового эл-та списка */
pt = (struct EL_SP*)malloc(sizeof(struct EL_SP));
strcpy_s(pt->id, t_id);
if (*p == NULL || strcmp(pt->id, (*p)->id) < 0)
{ /* включение ид-ра в начало списка */
pt->sled = *p;
*p = pt;
}
else
{ /* поиск элемента списка, после которого нужно
включить идентификатор */
k = *p; j = *p;
while (k != NULL && strcmp(pt->id, k->id) >= 0)
{
j = k;
k = k->sled;
}
/* включение эл-та *pt после элемента *j */
j->sled = pt; pt->sled = k;
}
}
/*-----------------------------------------------------------------*/
/* функция печати списка */
/*-----------------------------------------------------------------*/
void PechSp(struct EL_SP* p)
/* Вх. данные: p - указатель начала списка */
{
struct EL_SP* i;/* указатель текущего элемента списка */
printf("\nРезультат:\n");
for (i = p; i != NULL; i = i->sled)
{
puts(i->id);
}
}
int MassA(struct EL_SP* p, char* arr[255])
{
int k = 0;
printf("\nВведите число К:\n");
scanf_s("%d", &k);
printf("\nМассив A:\n");
struct EL_SP* h;
for (h = p; h != NULL; h = h->sled)
{
if (k < 255) {
strcpy_s(arr[k++], MAXDL, h->id);
}
else {
printf("Массив A заполнен полностью.\n");
break;
}
}
return k;
}
/*--------------------------------------------------------------*/
/* О С Н О В Н А Я П Р О Г Р А М М А */
/*-------------------------------------------------------------*/
int main()
{
setlocale(LC_ALL, "Rus");
struct EL_SP* p; /* указатель начала списка */
unsigned n; /* количество идентификаторов */
unsigned i, size; /* параметр цикла */
char t_id[MAXDL]; /* текущий идентификатор */
printf("\nВведите число идентификаторов\n n=");
scanf_s("%u", &n);
getchar(); /* пропуск символа "перевод строки" */
p = NULL; /* список пока пуст */
printf("Введите идентификаторы ");
printf("(после каждого нажимайте клавишу <Enter> )\n");
for (i = 1; i <= n; i++)
{
gets_s(t_id, MAXDL);
Vkl(&p, t_id); /* включение ид-ра в список */
}
PechSp(p);/* печать списка */
char* res[255];
size = MassA(p, res);
for (int i = 0; i < 255; i++) {
res[i] = (char*)malloc(MAXDL * sizeof(char));
printf("%s\0", res[i]);
free(res[i]);
}
printf("\n\nДля завершения нажмите любую клавишу\n");
_getch();
return 0;
}
Ответы (3 шт):
Переменная k
используется как индекс для массива arr
, но вы инкрементируете ее внутри цикла for
, который тоже использует переменную k
как условие для выхода из цикла.
Следовательно индекс k
выходит за пределы массива и получается переполнение буфера - нарушение прав доступа.
Чтобы убрать ошибку, следует назначить другую переменную для индексации массива arr
@tiovi Я же правильно изменил
int MassA(struct EL_SP* p, char* arr[255])
{
int y = 0;
printf("\nВведите число К:\n");
scanf_s("%d", &y);
printf("\nМассив A:\n");
struct EL_SP* h;
for (h = p; h != NULL; h = h->sled)
{
if (y < 255) {
strcpy_s(arr[y++], MAXDL, h->id);
}
else {
printf("Массив A заполнен полностью.\n");
break;
}
}
return y;
}
Извините если туплю, уже слишком долго с ним сижу)))
Вы заполняете массив arr в функции MassA до того, как выделили память в main (вызвали malloc). При вызове MassA массив res/arr в общем случае заполнен случайными значениями, поэтому при попытке записи по случайному адресу (strcpy_s(arr[k++], MAXDL, h->id)) возникает исключение. Выделять память необходимо до вызова MassA.