2010-10-29 41 views
17
const char* a; 

làm cách nào để đảm bảo rằng chuỗi 'a' bị hủy? khi a = "abcd" và tôi làm sizeof (a), tôi nhận được 4. Điều đó có nghĩa là nó không null-chấm dứt? nếu có, tôi sẽ nhận được 5?sizeof for a null terminated const char *

Trả lời

5

Nếu bạn được giao một mảng char có thể hoặc có thể không có dữ liệu không được chấm dứt trong đó, thực sự không có cách nào tốt để kiểm tra. Điều tốt nhất bạn có thể làm là tìm kiếm một ký tự null với độ dài xác định được xác định (không phải vô thời hạn!). Nhưng 0 không chính xác là một byte dữ liệu bất thường để tìm trong vùng bộ nhớ chưa được khởi tạo.

Đây là một trong nhiều điều về tiêu chuẩn chuỗi defacto của C mà nhiều người không thích. Tìm chiều dài của chuỗi mà khách hàng đưa cho bạn là hoạt động tìm kiếm O (n) ở mức tốt nhất và lỗi phân khúc ở mức thấp nhất.

Một vấn đề khác của khóa học là mảng và con trỏ có thể hoán đổi cho nhau.Điều đó có nghĩa là array_name + 2 giống với &(array_name[2])sizeof(a)sizeof(char*), không phải độ dài của mảng.

11

Bạn nhận được 4 vì đó là kích thước của con trỏ trên hệ thống của bạn. Nếu bạn muốn nhận được độ dài của chuỗi bị hủy bỏ, bạn muốn hàm strlen trong thư viện chuẩn C.

+0

'strnlen' cho an toàn. – nmichaels

+0

'strnlen' là nền tảng cụ thể, không phải trong tiêu chuẩn. – jer

+6

@Nathon: 'strnlen' không thực sự thêm an toàn, mặc dù, phải không? Nếu hàm của bạn yêu cầu một chuỗi null kết thúc và không nhận được một (hoặc nếu một hàm được chỉ định là trả về một chuỗi đã kết thúc null và không trả về một), thì mã của bạn đã bị hỏng. –

28

sizeof(a) cung cấp cho bạn kích thước của con trỏ, không phải của mảng ký tự mà con trỏ trỏ đến. Nó giống như bạn đã nói sizeof(char*).

Bạn cần phải sử dụng strlen() để tính chiều dài của một chuỗi null-chấm dứt (lưu ý rằng độ dài trở không bao gồm terminator null, nên strlen("abcd") là 4, không 5). Hoặc, bạn có thể khởi tạo một mảng có chuỗi chữ:

char a[] = "abcd"; 
size_t sizeof_a = sizeof(a); // sizeof_a is 5, because 'a' is an array not a pointer 

Chuỗi ký tự "abcd" không được kết thúc; tất cả các chuỗi ký tự không được kết thúc.

+1

OP đã sử dụng 'const', vì vậy' const char a [] 'có lẽ là một ý tưởng tốt hơn' char a [] '. – aschepler

+4

Để làm rõ hơn nữa, 'strlen()' sẽ chỉ cung cấp chiều rộng hợp lý của dữ liệu trong mảng char, không phải số byte được phân bổ cho nó. Tôi không nghĩ rằng có một cách để có được con số đó. –

4

sizeof(a)sizeof(const char*), kích thước của con trỏ. Nó không bị ảnh hưởng bởi nội dung của a. Đối với điều đó, bạn muốn strlen.

Ngoài ra, tất cả các chuỗi ký tự chuỗi được trích dẫn kép như số "abcd" trong mã nguồn của bạn sẽ tự động bị hủy.

1

sizeof (a) trả về kích thước của const char *a ... không phải kích thước của nội dung trỏ đến. Bạn có thể sử dụng strlen(a) để gind độ dài của chuỗi đã kết thúc null và không, kết quả của strlen không bao gồm null-terminator.

6

Vấn đề ở đây là bạn đang bối rối sizeof() là một hoạt động thời gian biên dịch với độ dài của chuỗi là một hoạt động thời gian chạy. Lý do lấy lại 4 khi bạn chạy sizeof(a)a là một con trỏ và kích thước điển hình của con trỏ trong C là 4 byte. Để có được độ dài của chuỗi sử dụng strlen.

Đối với câu hỏi thứ hai, cách đảm bảo chuỗi bị hủy. Cách duy nhất để dứt khoát làm điều này là vô hiệu hóa chuỗi của chính bạn. Chỉ với một char* không có cách nào để đảm bảo 100% nó là đúng null chấm dứt. Cần phải cẩn thận để đảm bảo hợp đồng giữa nhà sản xuất và người tiêu dùng của char* được hiểu là người chấm dứt chuỗi.

+0

aah .... ngu ngốc tôi. Nhưng khi tôi làm strlen (a) tôi nhận được 4, và tôi biết có một "abcd" (từ gdb). – hari

+0

@hari, 4 là chính xác vì độ dài của chuỗi "abcd" thực sự là 4. Tuy nhiên, yêu cầu bộ nhớ cho 'a' là' strlen (a) + 1' để xử lý dấu kết vô hạn. Đây là một trong những phần của C mà chỉ cần một chút làm quen với. – JaredPar

+0

Đó là vì độ dài của "abcd" là 4. strlen không tính toán terminator null. – jer

Các vấn đề liên quan