Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском.
Закрыт 1 год назад.
Задача программы: считать из файла строку, каждое слово из которой необходимо присвоить отдельному элементу массива. Далее, найти 3 самых длинных и 3 самых коротких слова, а затем вывести все слова в порядке, обратном алфавитному. Все задачи написанная мною программа решает, но я не могу очистить память. Проблема в куске программы, в котором элементам массива b присваивается строка из переменной token (все это в цикле while). Именно после сей действия не получается воспользоваться delete[]. Все массивы уже сделал одной размерности, но все равно не помогло. В чем может быть проблема? Код прилагаю ниже. Заранее спасибо!
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <stdlib.h>
#include <stdbool.h>
#include <iostream>
#include <locale.h>
#include <windows.h>
#include <ctype.h>
#include <fstream>
#include <malloc.h>
#include <conio.h>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
void bigswap(int i, int len, int biggest[]) {
if (len > biggest[0]) {
biggest[4] = biggest[2];
biggest[5] = biggest[3];
biggest[2] = biggest[0];
biggest[3] = biggest[1];
biggest[0] = len;
biggest[1] = i - 1;
}
else {
if (len > biggest[2]) {
biggest[4] = biggest[2];
biggest[5] = biggest[3];
biggest[2] = len;
biggest[3] = i - 1;
}
else {
if (len > biggest[4]) {
biggest[4] = len;
biggest[5] = i - 1;
}
}
}
}
void littleswap(int i, int len, int little[]) {
if (len < little[0]) {
little[4] = little[2];
little[5] = little[3];
little[2] = little[0];
little[3] = little[1];
little[0] = len;
little[1] = i - 1;
}
else {
if (len < little[2]) {
little[4] = little[2];
little[5] = little[3];
little[2] = len;
little[3] = i - 1;
}
else {
if (len < little[4]) {
little[4] = len;
little[5] = i - 1;
}
}
}
}
void gettext(char **b, int kolslov) {
printf("Слова, выведенные в порядке, обратном алфавитному:\n\n");
for (int i = 0; i < kolslov; i++) {
printf("%s\n", b[i]);
}
printf("\n\n");
}
void minusswap(char **b, int kolslov) {
for (int i = 0; i < (kolslov - 1); i++) {
for (int j = i + 1; j < kolslov; j++) {
if ((int)b[i][0] < 91) {
b[i][0] = (char)((int)b[i][0] + 32);
}
if ((int)b[j][0] < 91) {
b[j][0] = (char)((int)b[j][0] + 32);
}
if (strcmp(b[i], b[j]) < 0) swap(b[i], b[j]);
}
}
}
void initialization(int biggest[], int little[]) {
for (int i = 0; i < 6; i++) {
biggest[i] = -1;
little[i] = 100;
}
}
int main() {
char **b, *buffer, *token, delims[] = " \n.,!?/<>|)(*:;\"";
const int len_text = 300;
int max_len = 0, size_len = 0, Nslov = 0, kolslov = 0, menu = 0;
int biggest[6], little[6];
FILE *load = NULL;
setlocale(LC_ALL, "Russian");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
printf("Данная программа считывает ваш текст из файла, находит в нем три самых длинных и три самых коротких слова, а также располагает все слова в порядке, обратном алфавитному.\n\n\n");
system("pause");
system("cls");
for (;;) {
load = fopen("FILE.txt", "r");
fscanf_s(load, "%i\n", &kolslov);
initialization(biggest, little);
b = new char*[kolslov];
/*for (int i = 0; i < kolslov; i++) {
b[i] = new char[30];
}*/
buffer = new char[300];
token = new char[300];
fgets(buffer, len_text, load);
printf("Первоначальный текст:\n\n%s\n\n\nНайденные слова:\n\n", buffer);
token = strtok(buffer, delims);
int i = 0;
while (token != NULL)
{
int len = strlen(token);
b[i] = new char[300];
b[i] = token;
Nslov++;
printf("%s\n", b[i]);
i++;
bigswap(i, len, biggest);
littleswap(i, len, little);
token = strtok(NULL, delims);
}
printf("\n\nТри самых длинных слова в данном тексте:\n\n%s\n%s\n%s\n\n", b[biggest[1]], b[biggest[3]], b[biggest[5]]);
printf("\nТри самых коротких слова в данном тексте:\n\n%s\n%s\n%s\n\n\n", b[little[1]], b[little[3]], b[little[5]]);
minusswap(b, kolslov);
gettext(b, kolslov);
system("pause");
for (int i = 0; i < kolslov; i++) {
printf("\n%s\n", b[i]);
delete[] b[i];
}
delete[] b;
fclose(load);
system("pause");
system("cls");
}
system("pause");
}
Код того места, где появляется проблема, которая в дальнейшем вызывает ошибку:
while (token != NULL)
{
int len = strlen(token);
b[i] = new char[300];
b[i] = token;
Nslov++;
printf("%s\n", b[i]);
i++;
bigswap(i, len, biggest);
littleswap(i, len, little);
token = strtok(NULL, delims);
}
Код, при прохождении которого появляется ошибка:
for (int i = 0; i < kolslov; i++) {
printf("\n%s\n", b[i]);
delete[] b[i];
}
delete[] b;
Ошибка: вызвано срабатывание точки останова в функции delete_scalar.cpp
//
// delete_scalar.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Defines the scalar operator delete.
//
#include <crtdbg.h>
#include <malloc.h>
#include <vcruntime_new.h>
void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK);
#else
free(block);
#endif
}
Ошибка в строке: _free_dbg(block, _UNKNOWN_BLOCK);
Проблема явно с выделениями памяти. Мне к примеру очень не нравится переменная kolslov
- там может оказаться все, что угодно.
А причина похоже в строках b[i] = new char[300]; b[i] = token;
- вначале выделяем память, а потом ее перезатираем. Но это лишь цветочки. Массив token создан до входа в цикл. А это значит, что один и тот же массив будет присвоен элементам массива b
. И когда память освобождается, то пытаемся удалить один и тот же блок дважды. И получаем от runtime по пальцам.
Но потом я посмотрел ещё внимательней и понял, что тут все очень печально. Следим за руками:
delete[]
получает указатель в середину массива buffer и пытается его удалить, но это не самая лучшая идея и крешится.Что делать? как минимум, не заниматься писанием на си и полуручным управлением памятью (или все таки переписать все на си и поменять тег). Также не стоит смешить си и с++ функции. И напоследок, изучить, как работает strtok (и узнать, что она портит исходный массив. Но у нее есть парная функция, которая этого не делает).
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
У меня есть REST контроллер, который может удалять/вставлять/редактировать данные из бд, отображаю на jsp странице таблицу с соответствующими...
Сделал модальное окно с помощью jqueryВесь html код располагается на jsp странице, также использую spring-boot, tomcat