banner

[Rule] Rules  [Home] Main Forum  [Portal] Portal  
[Members] Member Listing  [Statistics] Statistics  [Search] Search  [Reading Room] Reading Room 
[Register] Register  
[Login] Loginhttp  | https  ]
 
Forum Index Thảo luận hệ điều hành Windows Con trỏ char và mảng kiểu char  XML
  [Programming]   Con trỏ char và mảng kiểu char 01/09/2006 11:02:28 (+0700) | #1 | 19722
[Avatar]
Thomas_Black
Member

[Minus]    0    [Plus]
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
[Profile] [PM]
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!
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 01/09/2006 11:26:58 (+0700) | #2 | 19732
facialz
Elite Member

[Minus]    0    [Plus]
Joined: 20/07/2004 03:48:17
Messages: 197
Location: HoChiMinh city
Offline
[Profile] [PM]

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.
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 01/09/2006 11:40:21 (+0700) | #3 | 19735
[Avatar]
Thomas_Black
Member

[Minus]    0    [Plus]
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
[Profile] [PM]
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 đó.
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 01/09/2006 12:49:59 (+0700) | #4 | 19761
facialz
Elite Member

[Minus]    0    [Plus]
Joined: 20/07/2004 03:48:17
Messages: 197
Location: HoChiMinh city
Offline
[Profile] [PM]
Ý 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 */
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 01/09/2006 21:21:42 (+0700) | #5 | 19818
[Avatar]
Thomas_Black
Member

[Minus]    0    [Plus]
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
[Profile] [PM]
Vậy theo pác thì thế này:
Code:
char c[100], *s;

s = c;

Là có thể dùng s như một string[100] phải không?
Thanks pác.
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 01/09/2006 22:14:37 (+0700) | #6 | 19837
[Avatar]
Z0rr0
Q+WRtaW5pc3RyYXRvc+g

Joined: 14/08/2002 12:52:01
Messages: 1323
Location: Underground
Offline
[Profile] [PM] [WWW] [Yahoo!]
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
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 02/09/2006 09:09:35 (+0700) | #7 | 20067
[Avatar]
Thomas_Black
Member

[Minus]    0    [Plus]
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
[Profile] [PM]
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à.
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 02/09/2006 11:34:01 (+0700) | #8 | 20096
[Avatar]
K4i
Moderator

Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
[Profile] [PM]
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
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 02/09/2006 12:13:08 (+0700) | #9 | 20105
[Avatar]
Thomas_Black
Member

[Minus]    0    [Plus]
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
[Profile] [PM]
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?
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 02/09/2006 17:46:26 (+0700) | #10 | 20146
[Avatar]
alice
Elite Member

[Minus]    0    [Plus]
Joined: 20/01/2005 22:23:24
Messages: 87
Location: Wonderland
Offline
[Profile] [PM]

Thomas_Black wrote:
Vậy theo pác thì thế này:
Code:
char c[100], *s;

s = c;

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. smilie
Như hà nghịch lỗ lai xâm phạm
如 何 逆 虜 來 侵 犯
[Up] [Print Copy]
  [Question]   Re: Con trỏ char và mảng kiểu char 03/09/2006 09:58:15 (+0700) | #11 | 20269
[Avatar]
K4i
Moderator

Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
[Profile] [PM]
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? smilie
Sống là để không chết chứ không phải để trở thành anh hùng
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 03/09/2006 10:28:58 (+0700) | #12 | 20272
[Avatar]
Thomas_Black
Member

[Minus]    0    [Plus]
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
[Profile] [PM]
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.
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 04/09/2006 11:17:58 (+0700) | #13 | 20502
[Avatar]
K4i
Moderator

Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
[Profile] [PM]
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
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 04/09/2006 16:16:55 (+0700) | #14 | 20551
[Avatar]
learn2hack
Elite Member

[Minus]    0    [Plus]
Joined: 29/06/2006 16:32:37
Messages: 825
Offline
[Profile] [PM] [WWW]
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
[Up] [Print Copy]
  [Question]   Con trỏ char và mảng kiểu char 05/09/2006 04:24:23 (+0700) | #15 | 20656
[Avatar]
Thomas_Black
Member

[Minus]    0    [Plus]
Joined: 14/07/2006 23:59:35
Messages: 51
Offline
[Profile] [PM]
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é.
[Up] [Print Copy]
  [Question]   Re: Con trỏ char và mảng kiểu char 10/12/2007 11:27:20 (+0700) | #16 | 103100
[Avatar]
_BlacK_EyE_
Member

[Minus]    0    [Plus]
Joined: 04/12/2007 05:47:44
Messages: 36
Offline
[Profile] [PM] [Yahoo!] [ICQ]
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:
int a;

lúc này a hiển nhiên được khởi tạo giá trị 0.
Còn với Code:
int *a

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:
int a, *p = &a;

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:
int *p = new int;

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:
int *a = new int;

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:
delete a;

sẽ tương đương với
Code:
HEAPPTR -= 4

Đồ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.
-----------------------------------------------------------------------
[Up] [Print Copy]
  [Question]   Re: Con trỏ char và mảng kiểu char 10/12/2007 14:22:37 (+0700) | #17 | 103141
FaL
Moderator

Joined: 14/04/2006 09:31:18
Messages: 1232
Offline
[Profile] [PM]

_BlacK_EyE_ wrote:
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
 


Windows làm cho việc quản lý bộ nhớ dễ dãi quá. Chẳng có con trỏ nào là "thông minh" cả. Có lẽ bạn chưa gặp lỗi trong việc cấp phát bộ nhớ, hoặc chưa bị đụng chạm những vùng nhớ nhạy cảm. Ví như đơn giản là lỗi "Segmenation fault" chẳng hạn. Trước đó tớ cũng mù mờ, và ko cấp phát. Từ ngày dính lỗi đó cứ phải cấp phát, kiểm tra cấp phát đàng hoàng.

Thân mến.
Hãy giữ một trái tim nóng và một cái đầu lạnh
[Up] [Print Copy]
  [Question]   Re: Con trỏ char và mảng kiểu char 10/12/2007 14:34:24 (+0700) | #18 | 103144
[Avatar]
_BlacK_EyE_
Member

[Minus]    0    [Plus]
Joined: 04/12/2007 05:47:44
Messages: 36
Offline
[Profile] [PM] [Yahoo!] [ICQ]
trích:
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ỏ.
[Up] [Print Copy]
  [Question]   Re: Con trỏ char và mảng kiểu char 27/12/2007 15:01:57 (+0700) | #19 | 106383
lam_y
Member

[Minus]    0    [Plus]
Joined: 19/11/2007 13:28:07
Messages: 4
Offline
[Profile] [PM]
pác cứ yên tâm đi pointer là con trỏ nên nó không ghi đè lên đâu/////
smilie
[Up] [Print Copy]
[digg] [delicious] [google] [yahoo] [technorati] [reddit] [stumbleupon]
Go to: 
 Users currently in here 
1 Anonymous

Powered by JForum - Extended by HVAOnline
 hvaonline.net  |  hvaforum.net  |  hvazone.net  |  hvanews.net  |  vnhacker.org
1999 - 2013 © v2012|0504|218|