Ết quả trả về là con trỏ đến xâu đã được nhập */

Một phần của tài liệu Bài giảng ngôn ngữ lập trình C (Trang 71)

/ *g ọi hàm g() biến b được cấp phát

kết quả trả về là con trỏ đến xâu đã được nhập */

void main() {

g();

/* gọi hàm g() biến b được cấp phát

trong g gọi đến f() nên biến a được cấp phát sau biến b

hàm f() kết thúc trước nên a được giải phóng trước rồi mới đến b */

}

Trong trường hợp chương trình có một hàm đệ qui được gọi. Mỗi lần hàm đệ qui được gọi là nó tự cấp phát biến cục bộ cho nó. Vì vậy nếu hàm đệ qui vơ tận thì các biến cục bộ sẽ được cấp phát không ngừng cho mỗi các lần gọi đệ qui. Từ đó sẽ dẫn đến lỗi tràn bộ nhớ stack (stack overflow) khi khơng cịn đủ ô nhớ trên stack để cấp phát biến cho lời gọi hàm đệ qui.

Một trong những lỗi thường gặp đối với một người viết chương trình C là tạo một hàm trả về kết quả là một con trỏ đến dữ liệu nằm trên stack. Rõ ràng là các ô nhớ trên stack sẽ được giải phóng khi hàm kết thúc nên các dữ liệu này sẽ khơng cịn nữa. Như vậy con trỏ lúc này sẽ không trỏ đến đúng dữ liệu hợp lệ.

Ví dụ có lỗi:

/* hàm u cầu người sử dụng nhập một xâu

kết quả trả về là con trỏ đến xâu đã được nhập */ */

char *nhapxau() {

char s[80];

printf("Nhap mot xau: "); gets(s);

return s;

/* trả về con trỏ đến mảng xâu s sẽ gây lỗi bộ nhớ

do nó sẽ bị giải phóng khi hàm kết thúc */

}

Ví dụ khơng có lỗi:

/* hàm yêu cầu người sử dụng nhập một xâu

kết quả trả về là con trỏ đến xâu đã được nhập */ */

char *nhapxau() {

char s[80];

printf("Nhap mot xau: "); gets(s);

/* dùng strdup để nhân đôi một xâu trong bộ nhớ động */

return strdup(s); /* kết quả trả về là xâu trong bộ nhớ động */ }

Chương trình mẫu (mangchuoi.c): Nhập và in một danh sách tên của các cá nhân.

#include <stdio.h>

/* hàm yêu cầu người sử dụng nhập một tên

Một phần của tài liệu Bài giảng ngôn ngữ lập trình C (Trang 71)