Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.10.2017, 18:43   #21
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Вообще, что такое n и зачем оно нужно?
Если это максимальная длина слова в файле,
то не забудьте, что еще должен быть '\0' в конце,
т.е. резервировать нужно n + 1 байт на слово.

И работайте с заранее подготовленным и проверенным файлом,
чтобы исключить ошибки связанные с генерацией данных.

Последний раз редактировалось Croessmah; 14.10.2017 в 18:52.
Croessmah вне форума Ответить с цитированием
Старый 14.10.2017, 18:51   #22
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Функцию забыл убрать просто... это не решает проблему, но если убрать всё, кроме выделения и освобождения памяти, то ок.
Значит, ошибка в заполнении массива. Хорошо. В чём может быть проблема? Может, в считывании
Код:
input >> strings[ind]
?
не литералом '\0' всё завершается? Смотрю - вроде, нет...
Haric_110 вне форума Ответить с цитированием
Старый 14.10.2017, 18:55   #23
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
Сообщение от Haric_110 Посмотреть сообщение
В чём может быть проблема?
1) Ошибка в данных в файле
2) n не учитывает '\0'.
Croessmah вне форума Ответить с цитированием
Старый 14.10.2017, 18:59   #24
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Цитата:
Сообщение от Croessmah Посмотреть сообщение
Вообще, что такое n и зачем оно нужно?
Если это максимальная длина слова в файле,
то не забудьте, что еще должен быть '\0' в конце,
т.е. резервировать нужно n + 1 байт на слово.
Да, Вы правы, проблема заключалась именно в этом... (пример файла данных я прикладывал к теме)

Спасибо! Говорил же, что ошибка очень проста)

Последний раз редактировалось Haric_110; 14.10.2017 в 19:02.
Haric_110 вне форума Ответить с цитированием
Старый 14.10.2017, 19:03   #25
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
Сообщение от Haric_110 Посмотреть сообщение
Говорил же, что ошибка очень проста
Только ошибка оказалась не в коде, а в данных.
Хотя и в коде тоже, как выяснилось, есть.


Код:
for (int ind_2 = 0; ind_2 < n; ++ind_2) strings[ind_1][ind_2] -= 'a';
Если слово по длине будет меньше n,
то '\0' также перепишется.
Как вариант:
Код:
char *wcur = strings[ind_1];
while (*wcur) {
   *wcur -= 'a';
   ++wcur;
}

Последний раз редактировалось Croessmah; 14.10.2017 в 19:06.
Croessmah вне форума Ответить с цитированием
Старый 14.10.2017, 19:10   #26
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Ну и используйте std::string, зачем Вам возня с char*?
многие присутствующие оптимизации в std::string,
вполне возможно, сделают код быстрее и эффективнее (а может и нет)))).
Например, gcc (емнип), сравнивает строки не по символам,
а более большими кусками (int'ами, вроде).
А при коротких строках (например, до 15 символов, включительно),
может быть применена оптимизация SSO,
которая исключит динамическую аллокацию памяти под строку.

Последний раз редактировалось Croessmah; 14.10.2017 в 19:18.
Croessmah вне форума Ответить с цитированием
Старый 14.10.2017, 19:12   #27
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Но это меня удивило.
Цитата:
Сообщение от Croessmah Посмотреть сообщение
Берем код с той же ошибкой:

Код:
#include <iostream>

int main()
{
    const int n = 3;
    int arr[n] = {555, 555, 555};
    int i = 0;
    while (i < n) {
        arr[i] = i++;
    }
    for(auto &e: arr) {
        std::cout << e << ", ";
    }
}
Смотрим на одном компиляторе (gcc): http://rextester.com/IAKLQC88748
Цитата:
555, 0, 1,
Смотрим на другом (CL): http://rextester.com/MSRRVL5172
Цитата:
0, 1, 2,
Оба поведения законны и ничего не нарушают в части языка,
но при выполнении будут проблемы,
мы же выходим за пределы массива.
Я бы не сказал, что поведение gcc законнно с точки зрения языка, он не различает преинкремент и постинкремент... или не совсем...
Как он вообще работает?
в вычислении индекса он инкрементирует i, а в присваивании — нет...

Последний раз редактировалось Haric_110; 14.10.2017 в 19:34.
Haric_110 вне форума Ответить с цитированием
Старый 14.10.2017, 19:23   #28
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Цитата:
Сообщение от Croessmah Посмотреть сообщение
Ну и используйте std::string, зачем Вам возня с char*?
Мне нужно преобразовать строки в массив чисел и с ними работать, а не с символами. Библиотеки плохо знаю — мой главный недостаток.
Цитата:
Сообщение от Croessmah Посмотреть сообщение
А при коротких строках (например, до 15 символов, включительно),
может быть применена оптимизация SSO,
которая исключит динамическую аллокацию памяти под строку.
Строки длиной до миллиона будут, так что, скорее всего, это не сработает... но я учту на будущее.

Последний раз редактировалось Haric_110; 14.10.2017 в 19:28.
Haric_110 вне форума Ответить с цитированием
Старый 14.10.2017, 19:24   #29
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
Сообщение от Haric_110 Посмотреть сообщение
Я бы не сказал, что поведение gcc законнно с точки зрения языка, он не различает прединкремент и постинкремент
Абсолютно законно.
Это ошибка программиста, он не знает правила C++.
А вот компиляторы эти правила знают.

Ошибка в том, что одна и та же переменная используется и изменяется в одном выражении.
И вот порядок этих изменений и использования в данном случае не определен.
Распишем то, как компилятор может переделать это выражение:
Код:
//arr[i] = i++;
//i = 0
//1:
temp_i = i;//temp_i = 0
++i; //i = 1
arr[temp_i] = temp_i;//arr[0] = 0;
//2
temp_i = i;//temp_i = 0
++i;//i = 1
arr[i] = temp_i;//arr[1] = 0;
//т.е. какое значение i нужно использовать в квадратных скобках?
//то, которое было до инкремента или значение после инкремента?
//правильный ответ - любое, в зависимости от хотелок компилятора
Можете почитать это: http://alenacpp.blogspot.ru/2005/11/...ce-points.html
Хоть точки следования несколько устаревшее понятие, но смысл тот же.

Последний раз редактировалось Croessmah; 14.10.2017 в 19:32. Причина: дополнил
Croessmah вне форума Ответить с цитированием
Старый 14.10.2017, 19:54   #30
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Первый вариант мне кажется логичным, я думал, так все и работают, а второй — нет.
Надеюсь, мне не придётся работать с компилятором, который будет думать не так, как думаю я)
Чёрт, я разочарован...
Haric_110 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Утечка памяти [Освобождение памяти массива] denis76560 Общие вопросы Delphi 4 27.11.2016 18:20
Объявление динамического двумерного массива kineziz Общие вопросы C/C++ 4 27.05.2012 15:40
Освобождение памяти под динамический массив tsar_ Общие вопросы Delphi 7 24.12.2011 00:37
Матрица из двумерного динамического массива. Abrokadawr Фриланс 5 03.11.2011 22:28
Освобождение динамического массива? VintProg Общие вопросы Delphi 15 28.08.2009 10:41