Các bác cho em hỏi:
Làm như trên liệu vùng nhớ phía sau ký tự o có được giải phóng không? Với lại theo các bác thì để cắt lấy 1 phần chuỗi thì nên dùng cách nào cho tối ưu nhất. Em mới học, còn gà nên mong các bác chỉ rõ rõ chút, vậy em mới hiểu được.PHP Code:char* alo;
strcpy(alo,"alo 1 2 3 4 5 6");
alo[3]=NULL;
MessageBox(0,alo,"alo",0);
MessageBox(0,alo,"alo",0);
Đã được chỉnh sửa lần cuối bởi lightingking : 04-06-2008 lúc 04:36 PM.
Bạn nói gì lạ vậy? Làm ơn xem lại dùm tớ chứ code trên tớ vẫn biên dịch và chạy ngon lành (MessageBox vẫn hiện lên với thông báo "alo" đấy thôi).strcpy
Còn về chuyện không được cấp phát vùng nhớ: nếu không cấp cho biến đó 1 vùng nhớ thì cả cái chuỗi "alo 1 2 3 4 5 6" sau khi được copy vào biến alo thì nó nằm ở đâu? Nó vẫn được cấp 1 vùng nhớ trên RAM để lưu chuỗi đó chứ.
Dùng một biến mà giá trị của nó chưa xác định là sai rất cơ bản. Lỗi này thì chỉ mới học lập trình vài ngày cũng không nên mắc phải. Nếu biến ấy là chỉ số hay con trỏ (nghĩa là gián tiếp hay trực tiếp nói lên địa chỉ của một biến khác) thì sai trầm trọng gấp bội: bạn đang truy nhập ra ngoài vùng bộ nhớ mà bạn đang cần và có thể đang phá hủy bộ nhớ của các phần khác của chương trình.
Bạn không được cấp gì cả. Đơn giản là bạn đang dùng 16 byte ở trong một vùng nhớ bạn không sở hữu và vì thế, không có quyền dùng. Việc chương trình vẫn chạy được có thể đơn giản chỉ là 16 byte này thuộc một vùng nhớ chưa được cấp, hoặc đã được cấp rồi nhưng chưa dùng, hoặc đã dùng rồi (và bị phá hủy rồi) nhưng bạn không biết. Thế thôi.
Cảm ơn bạn. Mình hiểu ý của bạn rồi, đúng là mình đã sai ở chỗ đó, rất cảm ơn vì đã nhắc nhở. Nhưng cái chính là mình muốn hỏi: nếu mình làm như vầy
thì liệu 12 byte đằng sau đó có được phá hủy hay không, hay là nó vẫn được coi là "có 1 chương trình đang sử dụng 12 byte đó, không chương trình nào được động đến 12 byte đó đâu đấy!" cho đến khi tắt máy tính.Code:char alo[]="alo 1 2 3 4 5 6"; alo[3]=NULL; MessageBox(0,alo,alo,0);
Nó không phá hủy. 16 byte này luôn thuộc về alo[] cho đến khi alo ngừng tồn tại (tức là khi thoát ra khỏi phạm vi khai báo của alo). Mặt khác, lệnh alo[3]=NULL (hoặc viết là alo[3] = '\0' nếu muốn sáng sủa hơn) có tác dụng "cắt xâu", làm cho các hàm xử lý c-string (xâu tận cùng bằng 0) như strlen(alo), strcpy(...,alo),... sẽ coi alo như một xâu có 3 kí tự. Vì thế, sau đó bạn có thể nối thêm tối đa 12 kí tự vào xâu alo, chẳng hạn bằng lệnh strcpy(alo, "123456789abc") mà vẫn đảm bảo an toàn.
Còn nếu trong mã nguồn ban đầu bạn tạo ra mảng bằng toán tử cấp phát bộ nhớ (new): char *alo = new char[16]; thì mảng này sẽ tồn tại đến khi nó bị hủy bởi toán tử thu hồi bộ nhớ (delete), hoặc nếu không bị delete thì đến tận khi kết thúc chương trình.
Cảm ơn Ada, bạn thật nhiệt tình. Giờ thì mình hiểu rồi. Bây giờ mình chỉ còn 1 thắc mắc: không biết có cách nào để hủy 1 chuỗi trong khi vẫn ở trong phạm vi khai báo nó không.
Hủy toàn bộ chuỗi hay hủy một đoạn cuối (phần thừa không dùng đến) của chuỗi?
Nếu cần hủy toàn bộ thì bạn có thể dùng new và delete.
Khai báo và dùng:
Hủy:Code:char *alo = new char[16]; // cấp 16 byte cho mảng không tên và cho alo trỏ vào đó a = alo[i]; // đọc mảng này thông qua alo ... alo[j] = b; // ghi mảng này thông qua alo
hoặcCode:delete [] alo; // hủy mảng không tên trước khi alo kết thúc phạm vi khai báo.
Code:blo = alo; // bây giờ có thể dùng mảng không tên này thông qua alo và cả blo ... // alo kết thúc phạm vi khai báo, nhưng blo vẫn còn delete [] blo; // hủy mảng không tên sau khi alo kết thúc phạm vi khai báo.