Nieprawidłowe dane w char*

0

Cześć mam taki dziwny problem, otóż do pewnej struktury zapasuje sobie ciąg znaków char * i w debuggerze ten ciąg znaków jest sensowny podczas wpisywania tej sekwencji, jednak przy wypisie wyskakują mi śmieciu, oto kod:

struct SField
{
	unsigned short m_nTag;
	const char * m_sValue;
	void * m_pNext; //wskaźnik na następny
};

SField* createSField(unsigned short m_nTag, string m_sValue)
{
	SField *sf = new SField;
	sf->m_nTag = m_nTag;
	sf->m_sValue = m_sValue.c_str();
	cout << sf->m_sValue << " --------------------------" << endl;
	sf->m_pNext = nullptr;
	return sf;
}

void addSField(SField ** head, unsigned short m_nTag, string m_sValue)
{
	
	if ((*head) == nullptr)
		(*head) = createSField(m_nTag, m_sValue);
	else
	{
		SField * helper = (*head);

		while (helper->m_pNext != nullptr)
		{
			helper = (SField*) helper->m_pNext;
		}
		helper->m_pNext = createSField(m_nTag, m_sValue);
	}
}

void writeSField(SField ** head)
{
	SField * helper = *head;

	while (helper != nullptr)
	{
		cout << helper->m_nTag << " " << (string)helper->m_sValue << endl;
		helper = (SField*) helper->m_pNext;
	}

}

Czy ktoś byłby w stanie pomóc?

2

c_str zwraca wskaźnik na tymczasowy ciąg znaków (ważny tak długo, jak istnieje oryginalna instancja tamtego std::stringa) - powinieneś ten ciąg znaków skopiować.

Dlaczego wolisz korzystać z nagich wskaźników, zamiast trzymać w strukture std::string?

1

W funkcji SField* createSField(unsigned short m_nTag, string m_sValue) robisz sf->m_sValue = m_sValue.c_str();. m_sValue jest przez funkcje przyjmowane przez kopie, stąd po wyjściu z funkcji obiekt m_sValue jak i m_sValue.c_str() jak i w konsekwencji sf->m_sValue nie istnieje. Te wskaźniki wskazują na usunięty już obszar pamięci.
Generalnie to jakbyś nie używał const char * czy void * to by było dobrze. Obrzydliwy jest ten kod i nie ma nic wspólnego z C++.

2

Na temat odpowiadaj w postach.

nie do końca rozumiem, kopiować w jaki sposób?

Na przykład poprzez zaalokowanie odpowiedniej ilości pamięci i odpalenie strcpy.

Tym niemniej: dlaczego w strukturze nie trzymasz std::string, tylko bawisz się w nagie wskaźniki?

1

czy jest na to jakiś lepszy sposób?

Tak: nie wykorzystuj w ogóle nigdy nagich wskaźników.

Zadam trzeci raz to samo pytanie: dlaczego w strukturze nie trzymasz po prostu std::string?

1

Powiedziałbym więcej. Twój sposób, kolego @krzysief jest najgorszy z możliwych.

0

panowie, generalnie to również nie podoba mi się sposób w jaki to robię, ale void * jak i const char* mam z góry zarzucone przez kogoś, kto układał zadanie i niestety muszę je wykonać w taki sposób

0

Zamień

sf->m_sValue = m_sValue.c_str();

na

sf->m_sValue = strdup(m_sValue.c_str());

Oczywiście bez free() wywołanym gdzieś na końcu programu (lub przy realokacji) będziesz miał wyciek pamięci, ale to możliwe że będzie na kolejnych zajęciach.
https://www.codingunit.com/c-tutorial-the-functions-malloc-and-free

5

Podeślij prowadzącemu https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete/ albo sprawdź, czy przypadkiem nie ma na ścianie kalendarza z 1995.

Ech panowie, mam nadzieję, że przejdzie ta nowelizacja ustawy i uczyć programowania będzie można tylko jak się samemu coś umie, bo niektórzy nie mają ani doświadczenia ani wyobraźni i np. każą użwać new/delete i nagich wskaźników jako nie-obserwerów...

1 użytkowników online, w tym zalogowanych: 0, gości: 1