@Acaunt

Почему Config::search у меня возвращает мусор?

Я - программист-любитель, не программист. Многого не знаю, только основы.

Хотел создать для своей программы конфигурационный файл. Для этого создал класс с функциями: обновление конфига, проверка существования конфига и поиск значений в конфиге.

config.h
#ifndef CONFIG_H_
#define CONFIG_H_

class Config {
private:
	static void update_config();
public:
	static int initialize();
	static const char* search(const char* parametr);
};

#endif /* CONFIG_H_ */


У меня все функции работают нормально кроме поиска значений Config::search. Он все нормально находит но только возвращает мусорные значения. Как это исправить?

Функция должна работает так: Config::search("title") возвращает NAME.
config.cpp
#include "Config.h"

#include <iostream>
#include <fstream>
#include <string>

std::ofstream w_config;
std::ifstream r_config;

void Config::update_config() {
	std::cout << "Create file Config" << std::endl;
	w_config.open("Config.ini");

	w_config << "title = NAME" << std::endl;
	w_config << "window_mode = 0" << std::endl;
	w_config << "width = 800" << std::endl;
	w_config << "hight = 600" << std::endl;

	w_config.close();
}

int Config::initialize() {
	r_config.open("Config.ini");
	if (!r_config.is_open()) {
		std::cout << "Have not file Config.ini" << std::endl;
		r_config.close();
		update_config();
		r_config.open("Config.ini");
	}

	if (!r_config.is_open()) {
		std::cerr << "Failed open file Config.ini" << std::endl;
		r_config.close();
		return -1;
	}

	else {
		std::cout << "Open file Config.ini" << std::endl;
		r_config.close();
		return 0;
	}
}

const char* Config::search(const char* parametr) {
	std::string str;
	for (int a = 0; a < 2; a++) {
		r_config.open("Config.ini");
		std::cout << "Search in file Config.ini -> " << parametr;

		while (!r_config.eof()) {
			r_config >> str;
			if (parametr == str) {
				std::getline(r_config, str);
				r_config.close();
				str.erase(0, 3);
				a = 2;
				break;
			}
			else {
				str = "";
			}
		}

		if (str == "") {
			r_config.close();
			std::cout << " -> not found" << std::endl;
			std::cout << "Re-";
			update_config();
		}
	}

	std::cout << " = " << str << std::endl;

	return str.c_str();
}
  • Вопрос задан
  • 301 просмотр
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Проблема вот в этой строчке:
return str.c_str();

Тут вы возвращаете указатель на внутренние данные у str. Но при выходе из функуции str уничтожается - это же локальная переменная. В итоге у вас получается висячий указатель (указатель на память, которой вы уже не владеете). Эту память какая-то другая часть вашей программы переиспользует и там остается что-то не ваше, выглядещее для вас, как мусор.

Вообще, это undefined behavior - доступ к висячему указателю. Программа вполне может и аварийно завершится.

Для решения этой проблемы возвращайте std::string. Или выделяйте char* вручную, через new[] (только не забудьте указатель потом удалить в вызывающем коде). Но лучше, конечно, возвращать string и не мучатся с ручным управлением указателями.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы