CodeInside
@CodeInside

Почему не удаётся записать символ в строку?

9-я строка кода выдаёт ошибку "Нарушение прав доступа по адресу".
#include <iostream>
#include <conio.h>
using namespace std;

void main()
{
	char * str1 = new char[6];
	str1 = "Lorem";
	str1[5] = '\0';
	char * str2 = "Lorem\0";

	printf("strlen(str1) = %d\tstrlen(str2) = %d\n", strlen(str1), strlen(str2));
	if (str1 == str2)
	{
		cout << str1 << " == " << str2;
	}
	else
	{
		cout << str1 << " != " << str2;
	}
	_getch();

	delete[] str1, str2;
}


Не могу понять вот такие вещи:
1) почему не могу записать символ (по любому индексу)?
2)почему выражение "str1 == str2" возвращает false, если строки идентичны?
3)почему в этом коде во все строки символ "\0" нормально записывается, а в строке "data[6][faculty_s] = '\0';" та же ошибка?

#include <iostream>
#include <conio.h>
#define MAX_LOGIN_SIZE 50
#define MAX_PASSWORD_SIZE 50
#define MAX_SURNAME_SIZE 32
#define MAX_NAME_SIZE 32
#define MAX_PATRONYMIC_SIZE 32
#define GROUP_NAME_SIZE 8//example "ECE-1511"
#define MAX_FACULTY_SIZE 21//"System administration"
using namespace std;

void main()
{
	FILE * accounts_w = nullptr;
	fopen_s(&accounts_w, "Accounts.dat", "wb");
	
	char * str = "Anto_cn69";
	short size = strlen(str);
	fwrite(&size, sizeof(size), 1, accounts_w);
	fputs(str, accounts_w);

	str = "4utc1";
	size = strlen(str);
	fwrite(&size, sizeof(size), 1, accounts_w);
	fputs(str, accounts_w);

	str = "Antonyuk";
	size = strlen(str);
	fwrite(&size, sizeof(size), 1, accounts_w);
	fputs(str, accounts_w);

	str = "Arkadiy";
	size = strlen(str);
	fwrite(&size, sizeof(size), 1, accounts_w);
	fputs(str, accounts_w);

	str = "Olegovich";
	size = strlen(str);
	fwrite(&size, sizeof(size), 1, accounts_w);
	fputs(str, accounts_w);

	int age = 18;
	fwrite(&age, sizeof(age), 1, accounts_w);

	str = "ECE-1511";
	size = strlen(str);
	fwrite(&size, sizeof(size), 1, accounts_w);
	fputs(str, accounts_w);

	str = "Programming";
	size = strlen(str);
	fwrite(&size, sizeof(size), 1, accounts_w);
	fputs(str, accounts_w);

	_getch();

	fclose(accounts_w);
	delete[] str;

	FILE * accounts = nullptr;//содержит данные учётных записей студентов
	fopen_s(&accounts, "Accounts.dat", "rb");

	char ** data = new char*[7];
	data[0] = new char[MAX_PASSWORD_SIZE + 1];
	data[1] = new char[MAX_SURNAME_SIZE + 1];
	data[2] = new char[MAX_NAME_SIZE + 1];
	data[3] = new char[MAX_PATRONYMIC_SIZE + 1];
	data[4] = new char[3];//2 цифры + '\0'
	data[5] = new char[GROUP_NAME_SIZE + 1];
	data[6] = new char[MAX_FACULTY_SIZE + 1];
	char temp_login[MAX_LOGIN_SIZE + 1];
	short log_s, pass_s, surn_s, name_s, patr_s, faculty_s;//_s - "size"

	fread(&log_s, sizeof(log_s), 1, accounts);
	fread(temp_login, sizeof(char), log_s, accounts);

	//пароль
	fread(&pass_s, sizeof(pass_s), 1, accounts);
	fread(data[0], sizeof(char), pass_s, accounts);
	data[0][pass_s] = '\0';

	//фамилия
	fread(&surn_s, sizeof(surn_s), 1, accounts);
	fread(data[1], sizeof(char), surn_s, accounts);
	data[1][surn_s] = '\0';

	//имя
	fread(&name_s, sizeof(name_s), 1, accounts);
	fread(data[2], sizeof(char), name_s, accounts);
	data[2][name_s] = '\0';

	//отчество
	fread(&patr_s, sizeof(patr_s), 1, accounts);
	fread(data[3], sizeof(char), patr_s, accounts);
	data[3][patr_s] = '\0';

	//возраст
	fread(&age, sizeof(age), 1, accounts);
	data[4][2];

	//группа
	fread(data[5], sizeof(char), GROUP_NAME_SIZE, accounts);
	data[5][GROUP_NAME_SIZE] = '\0';

	//факультет
	fread(&faculty_s, sizeof(faculty_s), 1, accounts);
	fread(data[6], sizeof(char), faculty_s, accounts);
	data[6][faculty_s] = '\0';

	for (short i = 0; i < 7; i++)
	{
		if (i == 4 || i == 6)
		{
			continue;
		}
		cout << data[i] << endl;
	}
	_getch();

И ещё один вопрос: как же всё-таки преобразовать int в char* (ибо система ругается на "_itoa_s(age,data[4], 2, 10);", а прежние версии этой ф-ции компилятор не пропускает)?
  • Вопрос задан
  • 115 просмотров
Решения вопроса 1
Поехали .
Char * str =бльбаблабла
Тут во-первых и так на конце будет нуль.
Если нет, значит в этой строке можно сразу нуль дописать.Врчд ли это будет нужно.
Область памяти только для чтении.

2. Гуглим сравнение строк и указателей
3.т ам выделана память на чтение и запись
А тут видимо выехали за границу. с мобилы плохо видно.
4. Нужно использовать только safe варианты и прочитать иныу о параметрах. Сейчас не подскажу
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
petermzg
@petermzg
Самый лучший программист
char * str1 = new char[6]; // тут вы выделяете 6 байт памяти
                                         // и присваиваете адрес выделенной памяти переменной str1
str1 = "Lorem"; // тут вы теряет ранее полученный адрес (утечка памяти)
                        // и переменной str1 присваиваете новый адрес из (not write access) блока памяти.
str1[5] = '\0';   // тут у вас уже проблема, так как на эту область памяти стоит защита от записи.

Содержимое строки нужно копировать в выделенную память
Ответ написан
Ваш ответ на вопрос

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

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