[Programming] [Question] Về vấn đề quản lý bộ nhớ với con trỏ trong C/C++ |
29/07/2008 05:31:46 (+0700) | #1 | 143878 |
|
K4i
Moderator
|
Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
|
|
Hi anh em,
Hôm nay tớ nhận được một cái mail của thằng em gửi cho như sau:
Code:
#include <iostream>
using namespace std;
int main()
{
char xau1[]="Tran huy hoang";
char *xau2="huy";
char *xau;
xau= strstr(xau1,xau2);
strncpy(xau,"han",3);
cout<<xau1<<endl;
system("pause");
return 0;
}
Anh ơi, sao khi khai báo: char xau1[]="Tran Huy Hoang" thì chương trình chạy được nhưng khai báo char *xau1="Tran Huy Hoang";
thì chương trình không chạy được. Em thấy hai khai báo này có gì khác nhau đâu ạ?
Thực sự là khi chạy chương trình, debug một hồi, không hiểu tại sao lỗi (dùng gcc và Code::Blocks để debug). Chỉ phát hiện lỗi nằm tại hàm strncpy. Lúc đầu là cứ nghĩ nguyên nhân là do việc thằng em này không cấp phát bộ nhớ cho con trỏ (đội mới học lập trình C/C++ rất hay bị lỗi đó) với lại để con trỏ chạy lung tung nên sinh lỗi. Sau đó, chuyển sang dùng VS C++ để debug thì mới phát hiện ra là lỗi Access Violation (tớ không nhớ lắm) đại khái là lỗi ghi vào vùng nhớ ko cho phép.
Đọc tài liệu một lúc (ở http://www.gotw.ca/gotw/009.htm và http://www.cs.bu.edu/teaching/cpp/string/array-vs-ptr/) thì tớ dự đoán nguyên nhân gây lỗi là thế này:
- Khi khai báo là con trỏ thì toàn bộ cái xâu "Tran huy hoang" sẽ được quẳng trong cái vùng Const Data và con trỏ xau1 sẽ chỉ thẳng đến vùng nhớ đó. Đáng tiếc là vùng nhớ này là chỉ đọc (read-only) nên cái hàm strncpy khi được gọi sẽ cố gắng thay đổi dữ liệu trên vùng nhớ này (thay xâu "huy" = "hân") nên gây lỗi.
- Khi khai báo là mảng, thì biến mảng xau1[] và dữ liệu được vứt vào Stack, vùng nhớ này có thể thay đổi được dữ liệu được nên khi gọi hàm strncpy sẽ ổn thỏa.
Tớ muốn mạn phép hỏi là tớ dự đoán có gì không chính xác không, xin các bác chỉ giáo. Nếu sai toét, thì mong anh em cho biết rõ hơn về nguyên nhân gây lỗi.
Tớ xin cảm ơn trước |
|
Sống là để không chết chứ không phải để trở thành anh hùng |
|
|
|
[Question] [Question] Về vấn đề quản lý bộ nhớ với con trỏ trong C/C++ |
29/07/2008 05:41:17 (+0700) | #2 | 143884 |
facialz
Elite Member
|
0 |
|
|
Joined: 20/07/2004 03:48:17
Messages: 197
Location: HoChiMinh city
Offline
|
|
K4i wrote:
Hi anh em,
Hôm nay tớ nhận được một cái mail của thằng em gửi cho như sau:
Code:
#include <iostream>
using namespace std;
int main()
{
char xau1[]="Tran huy hoang";
char *xau2="huy";
char *xau;
xau= strstr(xau1,xau2);
strncpy(xau,"han",3);
cout<<xau1<<endl;
system("pause");
return 0;
}
Anh ơi, sao khi khai báo: char xau1[]="Tran Huy Hoang" thì chương trình chạy được nhưng khai báo char *xau1="Tran Huy Hoang";
thì chương trình không chạy được. Em thấy hai khai báo này có gì khác nhau đâu ạ?
Thực sự là khi chạy chương trình, debug một hồi, không hiểu tại sao lỗi (dùng gcc và Code::Blocks để debug). Chỉ phát hiện lỗi nằm tại hàm strncpy. Lúc đầu là cứ nghĩ nguyên nhân là do việc thằng em này không cấp phát bộ nhớ cho con trỏ (đội mới học lập trình C/C++ rất hay bị lỗi đó) với lại để con trỏ chạy lung tung nên sinh lỗi. Sau đó, chuyển sang dùng VS C++ để debug thì mới phát hiện ra là lỗi Access Violation (tớ không nhớ lắm) đại khái là lỗi ghi vào vùng nhớ ko cho phép.
Đọc tài liệu một lúc (ở http://www.gotw.ca/gotw/009.htm và http://www.cs.bu.edu/teaching/cpp/string/array-vs-ptr/) thì tớ dự đoán nguyên nhân gây lỗi là thế này:
- Khi khai báo là con trỏ thì toàn bộ cái xâu "Tran huy hoang" sẽ được quẳng trong cái vùng Const Data và con trỏ xau1 sẽ chỉ thẳng đến vùng nhớ đó. Đáng tiếc là vùng nhớ này là chỉ đọc (read-only) nên cái hàm strncpy khi được gọi sẽ cố gắng thay đổi dữ liệu trên vùng nhớ này (thay xâu "huy" = "hân") nên gây lỗi.
- Khi khai báo là mảng, thì biến mảng xau1[] và dữ liệu được vứt vào Stack, vùng nhớ này có thể thay đổi được dữ liệu được nên khi gọi hàm strncpy sẽ ổn thỏa.
Tớ muốn mạn phép hỏi là tớ dự đoán có gì không chính xác không, xin các bác chỉ giáo. Nếu sai toét, thì mong anh em cho biết rõ hơn về nguyên nhân gây lỗi.
Bác đã dự đoán chính xác. Bác có thể viết một hàm rất đơn giản chỉ chứa mỗi lệnh char xau1[]="Tran huy hoang"; hay char *xau1 = "Tran huy hoang"; compile rồi decompile nếu muốn thấy tận mắt sự khác nhau này.
|
|
|
|
|
[Question] Re: [Question] Về vấn đề quản lý bộ nhớ với con trỏ trong C/C++ |
29/07/2008 05:43:21 (+0700) | #3 | 143885 |
|
secmask
Elite Member
|
0 |
|
|
Joined: 29/10/2004 13:52:24
Messages: 553
Location: graveyard
Offline
|
|
đồng ý với bác . |
|
|
[Question] Re: [Question] Về vấn đề quản lý bộ nhớ với con trỏ trong C/C++ |
29/07/2008 05:46:22 (+0700) | #4 | 143886 |
|
K4i
Moderator
|
Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
|
|
@facialz: không cần phải làm thế, tớ đã test thử
Code:
char *xau1 = "Tran huy hoang";
xau1[0] = 't';
cũng báo lỗi nên mới phán thế . Cơ bản là lâu không code lại C/C++ với lại chỉ biết mỗi Stack với Heap nên không chắc chắn lắm. Phải nhờ các bác có kinh nghiệm chỉ giúp |
|
Sống là để không chết chứ không phải để trở thành anh hùng |
|
[Question] Re: [Question] Về vấn đề quản lý bộ nhớ với con trỏ trong C/C++ |
29/07/2008 11:16:58 (+0700) | #5 | 143946 |
TQN
Elite Member
|
0 |
|
|
Joined: 29/06/2006 22:28:01
Messages: 888
Location: Biết làm chi ?
Offline
|
|
Compile = compiler nào, version mấy ? |
|
|
|