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 [Question] Về vấn đề quản lý bộ nhớ với con trỏ trong C/C++  XML
  [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
[Avatar]
K4i
Moderator

Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
[Profile] [PM]
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 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 smilie
Sống là để không chết chứ không phải để trở thành anh hùng
[Up] [Print Copy]
  [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

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

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 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.

[Up] [Print Copy]
  [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
[Avatar]
secmask
Elite Member

[Minus]    0    [Plus]
Joined: 29/10/2004 13:52:24
Messages: 553
Location: graveyard
Offline
[Profile] [PM] [WWW]
đồng ý với bác smilie.
[Up] [Print Copy]
  [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
[Avatar]
K4i
Moderator

Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
[Profile] [PM]
@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ế smilie. 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
[Up] [Print Copy]
  [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

[Minus]    0    [Plus]
Joined: 29/06/2006 22:28:01
Messages: 888
Location: Biết làm chi ?
Offline
[Profile] [PM] [WWW] [Yahoo!]
Compile = compiler nào, version mấy ?
[Up] [Print Copy]
  [Question]   Re: [Question] Về vấn đề quản lý bộ nhớ với con trỏ trong C/C++ 29/07/2008 11:40:54 (+0700) | #6 | 143951
[Avatar]
K4i
Moderator

Joined: 18/04/2006 09:32:13
Messages: 635
Location: Underground
Offline
[Profile] [PM]

TQN wrote:
Compile = compiler nào, version mấy ? 


Đầu tiên là MinGW v4.1, sau đó em vác sang Visual Studio C++ 2008 Express Edition dịch. Có chuyện gì ko bác smilie
Sống là để không chết chứ không phải để trở thành anh hùng
[Up] [Print Copy]
  [Question]   Re: [Question] Về vấn đề quản lý bộ nhớ với con trỏ trong C/C++ 29/07/2008 21:56:13 (+0700) | #7 | 143997
TQN
Elite Member

[Minus]    0    [Plus]
Joined: 29/06/2006 22:28:01
Messages: 888
Location: Biết làm chi ?
Offline
[Profile] [PM] [WWW] [Yahoo!]
/hvaonline/posts/list/16346.html
Lấy vd của cậu, build = command line, VC++ compiler của VS 2005, command line là cl.exe /DEBUG /Zi /W4 /EHsc test.cpp, run thấy không có lỗi gì cả. Quái.
Kết luận: phụ thuộc vào compiler và option.

[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|