2009-03-04 40 views
11

Tôi đã đặt bộ đệm thành kích thước 100. Tôi hiển thị bộ đệm trong chức năng chính nơi bộ đệm được khai báo. Tuy nhiên, khi tôi vượt qua bộ đệm để chức năng và nhận được sizeof '4', Tôi đã nghĩ nó nên là 100, vì đó là kích thước của bộ đệm mà tôi tạo ra trong chính. đầu ra: kích thước bộ đệm: 100 sizeof (đệm): 4chuyển bộ đệm char sang các chức năng và nhận kích thước của bộ đệm

#include <string.h> 
#include <stdio.h> 

void load_buffer(char *buffer); 

int main() 
{ 
    char buffer[100]; 
    printf("buffer size: %d\n", sizeof(buffer)); 
    load_buffer(buffer); 

    return 0; 
} 

void load_buffer(char *buffer) 
{ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 
+2

Trong chính() bạn khai báo rõ ràng một mảng, trong khi trong load_buffer() bạn khai báo một con trỏ. Sự khác biệt là, trong main() trình biên dịch biết rằng bộ đệm là một mảng, nhưng trong load_buffer() trình biên dịch không biết bộ đệm là từ một mảng hay một bộ nhớ được phân bổ trong bộ nhớ, hay cấu trúc hay bất cứ thứ gì . Trình biên dịch chỉ biết địa chỉ bộ nhớ (do đó một con trỏ), vì vậy sizeof() trả về kích thước của địa chỉ bộ nhớ, dài 4 byte (vì nó là một máy 32 bit, nếu nó là một máy 64 bit, nó sẽ là 8 byte dài). Hy vọng điều này sẽ giúp hiểu thêm một chút. – AndaluZ

+0

Thay vì hàm sizeof(), sử dụng strlen(), sau đó nó trả về kích thước của giá trị con trỏ. – NandhaKumar

Trả lời

19

Bạn đang sử dụng kích thước của con trỏ đến bộ đệm (4 byte), chứ không phải là kích thước của bộ đệm.

Trong C, bạn phải vượt qua kích thước của bộ đệm riêng biệt, một phần của lý do tràn bộ đệm xảy ra dễ dàng và thường xuyên.

void load_buffer(char * buffer, size_t bufSize) 
{  
    ... 
} 
4

Điều gì xảy ra, là khi bạn chuyển mảng vào hàm, bạn chỉ chuyển địa chỉ của mảng trong bộ nhớ chứ không phải kích thước của mảng. Sizeof (buffer) được đưa ra trong load_buffer() là kích thước của con trỏ, là bốn byte.

Cách tốt nhất để giữ cho kích thước của bộ đệm trong chức năng là thay đổi chức năng để:

void load_buffer(char *buffer, int length); 

và cuộc gọi đến:

load_buffer(buffer, sizeof(buffer)); 

và sau đó sử dụng chiều dài bất cứ khi nào bạn muốn kích thước của bộ đệm.

8

Từ OP

void load_buffer(char *buffer) 
{ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 

Mặc dù bạn có thể tưởng tượng rằng load_buffer() được thông qua buffer bởi refrence, những gì đang thực sự xảy ra là bạn đang đi qua một con trỏ đến char bởi giá trị . Mảng thực tế không được truyền vì vậy không có cách nào cho hàm load_buffer() để biết kích thước của mảng đệm

Vì vậy, sizeof(buffer) đang làm gì? Nó chỉ đơn giản là trả về kích thước của một con trỏ đến char. Nếu load_buffer() cần kích thước của buffer nó cần phải được thông qua speratly.

Hoặc bạn có thể tạo một cấu trúc mới có chứa cả một mảng char và kích thước của mảng, và vượt qua một con trỏ đến đó struct thay vào đó, cách mà các bộ đệm và kích thước của nó là luôn ở bên nhau;)

20

Các câu trả lời của Mitch Wheat và hhafez là hoàn toàn đúng và cho điểm. Tôi sẽ hiển thị một số thông tin bổ sung mà đôi khi có thể hữu ích.

Lưu ý rằng tương tự xảy ra nếu bạn nói với trình biên dịch rằng bạn có một loạt các kích thước phù hợp

void load_buffer(char buffer[100]) { 
    /* prints 4 too! */ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 

Một mảng như tham số chỉ được khai báo một con trỏ. Trình biên dịch sẽ tự động thay đổi điều đó thành char *name ngay cả khi nó được khai báo là char name[N].

Nếu bạn muốn để buộc người gọi phải vượt qua một loạt các kích thước 100 chỉ, bạn có thể chấp nhận địa chỉ của mảng (và loại đó) thay vì:

void load_buffer(char (*buffer)[100]) { 
    /* prints 100 */ 
    printf("sizeof(buffer): %d\n", sizeof(*buffer)); 
} 

Đó là một con trỏ đến mảng bạn có trong chính, vì vậy bạn cần phải dereference trong các chức năng để có được mảng. Lập chỉ mục sau đó được thực hiện bởi

buffer[0][N] or (*buffer)[N] 

Không ai biết rằng tôi đang làm điều đó và tôi không tự làm, bởi vì nó khá phức tạp khi vượt qua đối số. Nhưng nó là tốt để biết về nó. Bạn có thể gọi chức năng như thế này sau đó

load_buffer(&buffer) 

Nếu bạn muốn chấp nhận các kích thước khác quá, tôi sẽ đi với tùy chọn truyền N mà hai câu trả lời khác đề xuất.

+1

+1 Để thực hiện thêm một chút nỗ lực – Tom

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