[Programming] Con trỏ char và mảng kiểu char |
01/09/2006 11:02:28 (+0700) | #1 | 19722 |
|
Thomas_Black
Member
|
0 |
|
|
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
|
|
Hi hi, chào các bác, bác nào biết giáp đáp giùm em cái này nhé, em học lập trình bao năm rồi nhưng bi giờ mới để ý đến cái này.
Trong C (không phải C++) ko có kiểu string chính thống, dùng char * hoặc mảng kiểu char để thay thế. Nếu dùng mảng char thì không vấn đề gì rồi, nhưng nếu dùng char * thì có hại gì không? Ý em là đây là một pointer, liệu nó có ghi đè lên vùng dữ liệu khác nếu string của mình quá dài không?
Cảm ơn các pác! |
|
|
|
|
[Question] Con trỏ char và mảng kiểu char |
01/09/2006 11:26:58 (+0700) | #2 | 19732 |
facialz
Elite Member
|
0 |
|
|
Joined: 20/07/2004 03:48:17
Messages: 197
Location: HoChiMinh city
Offline
|
|
Thomas_Black wrote:
Hi hi, chào các bác, bác nào biết giáp đáp giùm em cái này nhé, em học lập trình bao năm rồi nhưng bi giờ mới để ý đến cái này.
Trong C (không phải C++) ko có kiểu string chính thống, dùng char * hoặc mảng kiểu char để thay thế. Nếu dùng mảng char thì không vấn đề gì rồi, nhưng nếu dùng char * thì có hại gì không? Ý em là đây là một pointer, liệu nó có ghi đè lên vùng dữ liệu khác nếu string của mình quá dài không?
Cảm ơn các pác!
Kiểu nào cũng có thể bị ghi đè hết. |
|
|
|
|
[Question] Con trỏ char và mảng kiểu char |
01/09/2006 11:40:21 (+0700) | #3 | 19735 |
|
Thomas_Black
Member
|
0 |
|
|
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
|
|
Pác không hiểu ý em rồi!
Ghi đè ở đây là ghi đè lên ô nhớ được biến khác chiếm hữu đó. Giống như trong Pascal dùng con trỏ mà không new là bị ghi đè lên ô nhớ đang chiếm hữu khác đó. |
|
|
|
|
[Question] Con trỏ char và mảng kiểu char |
01/09/2006 12:49:59 (+0700) | #4 | 19761 |
facialz
Elite Member
|
0 |
|
|
Joined: 20/07/2004 03:48:17
Messages: 197
Location: HoChiMinh city
Offline
|
|
Ý tui định nói lúc nãy là:
Code:
char c[100];
int x;
c[100] = 100; /* ghi đè lên x */
Hì hì, tui post code rồi mới biết là lầm. Compiler chắc sẽ phát hiện ra lỗi trong code trên. Code coi như không có.
Còn về câu hỏi của bồ, char* rùi vẫn phải cấp phát bộ nhớ cho nó. Nếu lỡ trật chỉ số thì vẫn bị ghi đè ra ngoài như thường:
Code:
char *c = malloc(100*sizeof(char));
c[100] = 100; /* ghi đè ra ngoài mảng */
|
|
|
|
|
[Question] Con trỏ char và mảng kiểu char |
01/09/2006 21:21:42 (+0700) | #5 | 19818 |
|
Thomas_Black
Member
|
0 |
|
|
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
|
|
Vậy theo pác thì thế này:
Code:
Là có thể dùng s như một string[100] phải không?
Thanks pác. |
|
|
|
|
[Question] Con trỏ char và mảng kiểu char |
01/09/2006 22:14:37 (+0700) | #6 | 19837 |
|
Z0rr0
Q+WRtaW5pc3RyYXRvc+g
|
Joined: 14/08/2002 12:52:01
Messages: 1323
Location: Underground
Offline
|
|
khi khai báo char *s thì s là pointer, nó có thể chưa địa chỉ của bất kì vùng nhớ nào trong giới hạn virtual memory của hệ thống. Tuy nhiên khi muốn cấp phát (allocate) 1 vùng nhớ có kích thước cụ thể cần quan tâm đến khả năng overflow, xảy ra khi ghi dữ liệu ra ngoài vùng con trỏ quản lý. |
|
Hibernating |
|
|
|
[Question] Con trỏ char và mảng kiểu char |
02/09/2006 09:09:35 (+0700) | #7 | 20067 |
|
Thomas_Black
Member
|
0 |
|
|
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
|
|
Cái đó em hiểu mà.
Thực ra em chỉ muốn hỏi là nếu dùng char * mà chỉ khai báo thôi mà không cấp phát bộ nhớ (thí dụ trỏ vào 1 mảng char) thì có thể có khả năng bị ghi đè lên vùng nhớ khác không ấy mà. |
|
|
|
|
[Question] Con trỏ char và mảng kiểu char |
02/09/2006 11:34:01 (+0700) | #8 | 20096 |
|
K4i
Moderator
|
Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
|
|
Trong bộ nhớ của C có 2 vùng nhớ là Heap và Stack. Khi bạn khai báo một con trỏ (pointer) chẳng hạn thì vùng nhớ được cấp phát sẽ là vùng nhớ trên Heap. Trong khi đó, các biến khác khi khai báo sẽ được cấp phát bộ nhớ trên Stack. Khi sử dụng con trỏ trỏ vào một biến nào đó thì vùng nhớ của con trỏ trên Heap sẽ được trỏ tới vùng nhớ trên Stack. Chính vì vậy khi bạn không cung cấp vùng nhớ cho con trỏ (hay không cấp phát bộ nhớ cho nó) thì sẽ không có chuyện bộ nhớ trên Stack bị ghi đè. Tuy nhiên, việc khai báo con trỏ mà không cấp phát sẽ rất nguy hiểm, khiến cho chương trình đi lúc nào không hay.
Còn khi bạn đã cho nó trỏ tới một mảng char chẳng hạn, tức là bạn đã cấp phát cho con trỏ một vùng nhớ rồi, thì sẽ không có chuyện bị ghi đè dữ liệu lên vùng nhớ khác đâu. |
|
Sống là để không chết chứ không phải để trở thành anh hùng |
|
|
|
[Question] Con trỏ char và mảng kiểu char |
02/09/2006 12:13:08 (+0700) | #9 | 20105 |
|
Thomas_Black
Member
|
0 |
|
|
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
|
|
Thanks pác. Điều pác nói, em biết, nhưng em thấy pác có một chỗ không chính xác thì phải. Nếu không cấp phát bộ nhớ thì lúc đó con trỏ đang trỏ lung tung, có thể trỏ vào vùng nhớ quan trọng của biến khác chứ, nghĩa là vùng nhớ của biến đó có thể bị ghi đè mà.
Tóm lại, ý mọi người là khi khai báo con trỏ, nhất thiết phải cấp phát bộ nhớ mà không được sử dụng luôn đúng không? |
|
|
|
|
[Question] Con trỏ char và mảng kiểu char |
02/09/2006 17:46:26 (+0700) | #10 | 20146 |
|
alice
Elite Member
|
0 |
|
|
Joined: 20/01/2005 22:23:24
Messages: 87
Location: Wonderland
Offline
|
|
Thomas_Black wrote:
Vậy theo pác thì thế này:
Code:
Là có thể dùng s như một string[100] phải không?
Thanks pác.
Bạn có thể dùng s như c. |
|
Như hà nghịch lỗ lai xâm phạm
如 何 逆 虜 來 侵 犯 |
|
|
|
[Question] Re: Con trỏ char và mảng kiểu char |
03/09/2006 09:58:15 (+0700) | #11 | 20269 |
|
K4i
Moderator
|
Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
|
|
có thể trỏ vào vùng nhớ quan trọng của biến khác chứ, nghĩa là vùng nhớ của biến đó có thể bị ghi đè mà.
==> đồng ý là thế, nhưng không có nghĩa là vùng nhớ đó bị ghi đè. Bởi vì, vùng nhớ của con trỏ là nằm trên Heap, không phải Stack. Nó chỉ trỏ tới 1 vùng nhớ nào đó trên Stack. Vậy thì ý bạn ở đây, ghi đè nghĩa là sao? Chẳng lè Heap có thể nằm đè lên Stack.
ý mọi người là khi khai báo con trỏ, nhất thiết phải cấp phát bộ nhớ mà không được sử dụng luôn đúng không
==> không hiểu. Đã khai báo, đã cấp phát mà không sử dụng thì để làm mắm ah? |
|
Sống là để không chết chứ không phải để trở thành anh hùng |
|
|
|
[Question] Con trỏ char và mảng kiểu char |
03/09/2006 10:28:58 (+0700) | #12 | 20272 |
|
Thomas_Black
Member
|
0 |
|
|
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
|
|
Ha ha, bác nhầm rồi, khi cấp phát bộ nhớ C mới cung cấp cho nó một vùng nhớ trên Heap, chứ bình thường, nó có thể trỏ bất kỳ đâu có thể Heap, có thể Stack, vùng nhớ bị ghi đè ở đây là ý em muốn nói giá trị của biến đang chiếm hữu vùng nhớ đó có thể bị thay đổi, hay nói cách khác là 2 biến cùng trỏ một vùng nhớ.
ý mọi người là khi khai báo con trỏ, nhất thiết phải cấp phát bộ nhớ mà không được sử dụng luôn đúng không
==> không hiểu. Đã khai báo, đã cấp phát mà không sử dụng thì để làm mắm ah?
Có nghĩa là phải cấp phát trước khi sử dụng ấy. |
|
|
|
|
[Question] Con trỏ char và mảng kiểu char |
04/09/2006 11:17:58 (+0700) | #13 | 20502 |
|
K4i
Moderator
|
Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
|
|
vùng nhớ bị ghi đè ở đây là ý em muốn nói giá trị của biến đang chiếm hữu vùng nhớ đó có thể bị thay đổi, hay nói cách khác là 2 biến cùng trỏ một vùng nhớ.
==> chính xác.
Có nghĩa là phải cấp phát trước khi sử dụng ấy.
==> bạn hiểu rồi, còn gì nữa.
|
|
Sống là để không chết chứ không phải để trở thành anh hùng |
|
|
|
[Question] Con trỏ char và mảng kiểu char |
04/09/2006 16:16:55 (+0700) | #14 | 20551 |
|
learn2hack
Elite Member
|
0 |
|
|
Joined: 29/06/2006 16:32:37
Messages: 825
Offline
|
|
1 nguyên tắc khi sử dụng con trỏ là phải cấp phát bộ nhớ cho nó trước khi sử dụng. nếu không cấp phát bộ nhớ cho nó thì có thể nó đang trỏ đến những vùng dữ liệu quan trọng của hệ thống, và việc sử dụng nó sẽ gây ra những hậu quả không biết trước được.
do đó đúng như bạn nói đó, phải cấp phát trước khi sử dụng.
còn trước khi cấp phát vùng nhớ cho nó, nó chỉ là 1 pointer, và khi đó bạn cho nó trỏ đến đâu cũng được, và có thể cho nhiều poiter trỏ đến cùng 1 vùng nhớ (1 biến, mảng chẳng hạn). khi đó việc dùng trực tiếp tên biến, mảng hay việc sử dụng tên pointer để truy cập vào vùng nhớ đó là như nhau. |
|
Blog: http://hontap.blogspot.com
Tải phần mềm miễn phí: http://www.taiphanmem.org |
|
|
|
[Question] Con trỏ char và mảng kiểu char |
05/09/2006 04:24:23 (+0700) | #15 | 20656 |
|
Thomas_Black
Member
|
0 |
|
|
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
|
|
Vấn đề em hỏi chỉ có vậy thôi, cảm ơn các bác nhiều, em đã hiểu rồi.
Bác Mod nào close luôn topic này giùm em nhé. |
|
|
|
|
[Question] Re: Con trỏ char và mảng kiểu char |
10/12/2007 11:27:20 (+0700) | #16 | 103100 |
|
_BlacK_EyE_
Member
|
0 |
|
|
Joined: 04/12/2007 05:47:44
Messages: 36
Offline
|
|
learn2hack quote:
1 nguyên tắc khi sử dụng con trỏ là phải cấp phát bộ nhớ cho nó trước khi sử dụng. nếu không cấp phát bộ nhớ cho nó thì có thể nó đang trỏ đến những vùng dữ liệu quan trọng của hệ thống, và việc sử dụng nó sẽ gây ra những hậu quả không biết trước được.
do đó đúng như bạn nói đó, phải cấp phát trước khi sử dụng.
-----> không đúng.
Nếu là một con trỏ thông minh, nó sẽ tự biết khởi tạo giá trị cho nó. Giống như khi ta khai báo
Code:
lúc này a hiển nhiên được khởi tạo giá trị 0.
Còn với Code:
thì khác. Con trỏ a lúc này nhận một giá trị nào đó ( địa chỉ của một ô nhớ nào đó ) mà ta không biết. Chẳng nhẽ , ta sử dụng một biến mà lại không biết nó bằng bao nhiêu? Bởi thế có thể gán cho nó một giá trị bất kì ( mà ta biết ). Trong trường hợp này, cái mà ta gán là một địa chỉ.
Bởi thế, có thể khởi tạo bằng cách sau:
Code:
Lúc này p = địa chỉ của a . Như thế ta đã biết p trỏ đi đâu.
Cái thứ hai, nếu nói như thế thì
Code:
làm gì có khởi tạo nào đâu? ( tức là phép gán địa chỉ cho con trỏ p)
Muốn hiểu rõ vấn đề này, ta hãy xem cấu trúc của heap.
Nó là một vùng nhớ truy cập ngẫu nhiên ( giống như RAM vậy) , có dung lượng khoảng 200-300Kbytes ( trong khi dung lượng segment dữ liệu của chương trình là 64KB và stack chỉ là 16KB).Nó nằm ngay sau code của chương trình. Nó có 3 con trỏ quản lý.
HEAPORG: trỏ đến đỉnh HEAP
HEAPPTR: con trỏ hiện thời
HEAPEND: đáy heap.
Bây giờ, nếu không muốn dùng heap thì thôi, ta có thể dùng con trỏ trỏ đến đâu đó trong vùng dữ liệu của chương trình ( 64KB). Còn nếu muốn tạo một biến trong heap. Ta phải dùng con trỏ. Tại sao?
Đơn giản là vì cách truy nhập vào heap chỉ có thể thông qua 3 con trỏ của HEAP ở trên.
Như thế, có thể phân tích như sau:
Code:
sẽ tương đương với
Code:
int *a = HEAPORG; // địa chỉ của đỉnh HEAP
HEAPPTR += 4 ; // sizeof(int) = 4
và sau đó giá trị vùng nhớ trên heap tự động gán bằng 0.
Tiếp tục
Code:
sẽ tương đương với
Code:
Đồng thời giá trị trên HEAP trở về 0
Code:
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
int *a = new int(4);
delete a;
cout << *a << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Ở code trên , sau khi delete a, ta vẫn có thể hiển thị (*a) ra màn hình được, nhưng lúc này, không phải 4, mà là 0.
----------------------------------------------------------------------- |
|
|
|
|
|