Thắc mắc giải phóng bộ nhớ động trong VS C++

#include <iostream>
#include <string>


using namespace std;
char* tach(const char* s)
{
	char* str = new char;
	int i;
	for (i = 0; s[i] != NULL; i++)
		if (s[i] != ' ')
			str[i] = s[i];
		else
			break;
	str[i] = NULL;
	return str;
}

int main()
{
	char* s;
	s = tach("viet nam");
	cout << s << endl;
	delete s;

	return 0;
}

Đề bài: Viết chương trình tách 1 từ ra khỏi 1 xâu kí tự
Mọi người có thể cho em hỏi khi em code như ở trên thì trên VS nó báo lỗi Debug Error! (HEAP CORRUPTION DETECTED…) ạ. Còn khi em thử trên codeblocks thì vẫn chạy bình thường
Em thử sửa lại thành như này

#include <iostream>
#include <string>


using namespace std;
char* tach(const char* s)
{
	char* str = new char[strlen(s) + 1];
	int i;
	for (i = 0; s[i] != NULL; i++)
		if (s[i] != ' ')
			str[i] = s[i];
		else
			break;
	str[i] = NULL;
	return str;
}

int main()
{
	char* s;
	s = tach("viet nam");
	cout << s << endl;
	delete[] s;

	return 0;
}

thì trên VS lại chạy được bình thường ạ
Ai có thể giải thích giúp em với được không ạ? Em cảm ơn!

Bạn nên nhớ rằng Visual Studio C++ chế độ debug nó khác các compiler khác ở cái cơ chế kiểm tra heap corruption khá là nghiêm ngặt của nó, bên CodeBlock nó dùng Gcc thì không nghiêm ngặt bằng đâu.

Và bạn thử ngồi xuống, đọc từng dòng code trong hàm “tach” và giải thích xem thử nào, bởi vì trông như thể bạn đang sao chép chuỗi (trừ khoảng trắng), chả thấy “Tách” ở chỗ nào cả. Bạn còn chẳng nói rõ kết quả như thế nào thì đáng gọi là “đã tách”.

Với lại:

s = tach("viet nam");
cout << s << endl;
delete[] s;

Cái này mình hay gọi là “gây bất ngờ” cho độc giả, vì bạn tạo ra dữ liệu nhưng bắt “người khác” phải delete giùm bạn.

2 Likes

Code đầu tiên có vấn đề ở đây, vì không chỉ rõ size cần cấp nên khi chạy chương trình sẽ ngoẻo. Codeblocks chạy được thì không hiểu tại sao, nhưng C với C++ là như vậy, thi thoảng lỗi rành rành ra vẫn có cái chạy cái ngoẻo, vì các Compiler của C và C++ có quá nhiều xuât xứ nguồn gốc( nhiều bên phát triển)

đoạn sửa như này là chạy ngon, vì đã chỉ rõ là cần phải cấp cho cái chuỗi str kia 1 khoảng len+1 phần tử trong HEAP, mỗi phần tử có size kiểu char là 1 byte.

Cái này nên sửa thành str[i] = ‘\0’.

Về vấn đề này có thể nói thêm như này: Khi dùng bộ nhớ động , bạn cấp bộ nhớ ở đâu thì nên hủy ở đó, nghĩa là cả lệnh cấp bộ nhớ và lệnh hủy bộ nhớ đã cấp nên nằm trong cùng 1 hàm hoặc 1 block code chứ không nên cấp ở 1 hàm, hủy ở 1 chỗ khác ( như trên là cấp bộ nhớ trong hàm tách, hủy trong hàm main )
bạn có thể tham khảo như này :

main :
 // đếm size của chuỗi cần tách
size = ...

// cấp bộ nhớ
char* str = malloc(size+1);

// truyền str và size vào chỗ cần sử dụng
tach( str , size );

// hủy
free( str );
2 Likes

Sorry bạn, đề chính xác là viết chương trình tách từ đầu tiên ra khỏi xâu kí tự, lần sau mình sẽ để ý hơn. Cảm ơn bạn đã đóng góp ý kiến ạ

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?