2013-09-28 299 views
18

Tôi đang cố gắng viết một chương trình đọc trong một chuỗi các chuỗi từ một tệp văn bản và lưu trữ chúng trong một chuỗi các chuỗi, phân bổ động bộ nhớ cho mỗi phần tử. Kế hoạch của tôi là để lưu trữ mỗi chuỗi trong một mảng bằng cách sử dụng một con trỏ và sau đó phát triển kích thước mảng như nhiều hơn đã được đọc in Tôi đang gặp khó khăn để hiểu tại sao mã thử nghiệm của tôi dưới đây không hoạt động. Đây có phải là một ý tưởng khả thi?Phân bổ bộ nhớ động cho mảng con trỏ

char *aPtr; 
aPtr =(char*)malloc(sizeof(char)); 

aPtr[0]="This is a test"; 


printf("%s",aPtr[0]); 
+1

Điều này không hoạt động vì bạn 'không gian malloc' cho một ký tự đơn lẻ, và sau đó bạn cố gán toàn bộ chuỗi cho một giá trị' char' đã nhập. –

+0

Đề nghị đọc: [Khi nào tôi nên sử dụng malloc trong C và khi nào tôi không?] (Http://stackoverflow.com/a/1963812/2455888). – haccks

Trả lời

15

Trong C chuỗi là char*. Mảng động của loại T được biểu thị dưới dạng con trỏ đến T, vì vậy đối với char* sẽ là char**, không chỉ đơn giản là cách char* theo cách bạn khai báo.

Trình biên dịch, không nghi ngờ gì, đã đưa ra một số cảnh báo về nó. Chú ý đến những cảnh báo này, rất thường xuyên chúng giúp bạn hiểu phải làm gì.

Đây là cách bạn có thể bắt đầu thử nghiệm của bạn:

char **aPtr; 
int len = 1; // Start with 1 string 
aPtr = malloc(sizeof(char*) * len); // Do not cast malloc in C 
aPtr[0] = "This is a test"; 
printf("%s",aPtr[0]); // This should work now. 
+0

Để xác minh (hãy mang theo tôi, tôi là newbie =]), nếu bạn muốn một mảng động của con trỏ đến char (ví dụ, khi cần thiết trong một ứng dụng mà bạn có thể cần lưu trữ một chuỗi ký tự số đọc một tập tin văn bản mà không biết chiều dài của nó hoặc thu thập đầu vào của người dùng không xác định chiều dài), sau đó bạn cần một mảng động của Char * và vì vậy bạn sẽ cần một Char **. Ký tự char ** có thể trỏ đến các con trỏ ký tự khác nhau, có thể là địa chỉ bắt đầu của các chuỗi ký tự khác nhau. –

+0

'len = 1' ở đây là gì? Nó trông giống như 'Đây là một thử nghiệm' sẽ là 14 ký tự, đó là mỗi một byte .... nhưng mã này không đề cập đến 14, cũng không segfault khi tôi chạy. – nmz787

+0

@ nmz787 Lưu ý loại 'aPtr', đó là một con trỏ đôi, do đó, đại diện cho một mảng các con trỏ char. Một con trỏ char sau đó được đặt thành phần tử 0; không có chuỗi sao chép đang xảy ra trong mã này. – dasblinkenlight

5
char * aPtr; 

là như con trỏ đến một nhân vật, mà bạn phân bổ bộ nhớ để giữ chính xác 1 nhân vật.

Làm

aPrt[0] = "test"; 

bạn giải quyết bộ nhớ cho điều này một nhân vật và cố gắng để lưu trữ các địa chỉ của các literal "test" với nó. Điều này sẽ thất bại vì địa chỉ này hầu hết là rộng hơn sau đó một nhân vật.

Sửa lỗi cho mã của bạn sẽ là cấp phát bộ nhớ cho con trỏ đến một ký tự.

char ** aPtr = malloc(sizeof(char *)); 
aPtr[0] = "test"; 
printf("%s", aPtr[0]); 

Are thanh lịch ngày càng nhiều trên cách tiếp cận mạnh mẽ sẽ được phân bổ như nhau (cũng như thêm các kiểm tra lỗi bắt buộc) bằng cách thực hiện:

char ** aPtr = malloc(sizeof *aPtr); 
if (NULL == aPtr) 
{ 
    perror("malloc() failed"); 
    exit(EXIT_FAILURE); 
} 

... 
9
char *str; //single pointer 

Với điều này bạn có thể lưu trữ một chuỗi.


Để lưu array of strings bạn cần two dimensional character array

hoặc khác array of character pointers hoặc khác double pointer


char str[10][50]; //two dimensional character array 

Nếu bạn khai báo như thế này bạn không cần phải cấp phát bộ nhớ vì đây là tĩnh khai


char *str[10]; //array of pointers 

Ở đây bạn cần phải phân bổ bộ nhớ cho mỗi con trỏ

lặp qua mảng để cấp phát bộ nhớ cho mỗi con trỏ

for(i=0;i<10;i++) 
str[i]=malloc(SIZE); 

char **str; //double pointer 

Ở đây bạn cần phải phân bổ bộ nhớ cho Số con trỏ và sau đó cấp phát bộ nhớ cho mỗi con trỏ.

str=malloc(sizeof(char *)*10); 

Và sau đó lặp qua mảng cấp phát bộ nhớ cho mỗi con trỏ

for(i=0;i<10;i++) 
str[i]=malloc(SIZE); 
-1

Bạn đang làm việc đó hoàn toàn sai. Phiên bản đúng của mã của bạn phải như sau:

int main() 
{ 
char *aPtr; 
aPtr =(char*)malloc(20*sizeof(char)); 
aPtr ="This is a test"; 
printf("%s",aPtr); 
} 

Bạn có thể sử dụng mảng con trỏ. nếu bạn muốn lưu trữ nhiều chuỗi. Có, tôi biết sử dụng vòng lặp sẽ dễ dàng. Nhưng tôi đang cố gắng giải thích một cách đơn giản ngay cả người mới bắt đầu cũng có thể hiểu được.

int main() 
{ 
char *aPtr[10]; 
aPtr[0] =(char*)malloc(20*sizeof(char)); 
aPtr[0] ="This is a test"; 
aPtr[1] =(char*)malloc(20*sizeof(char)); 
aPtr[1] ="This is a test2"; 
printf("%s\n%s\n",aPtr[0],aPtr[1]); 
} 
+0

Ví dụ đầu tiên của bạn làm rò rỉ bộ nhớ, cụ thể là 20 byte. Làm 'aPtr =" Đây là một thử nghiệm ";' bạn mất tham chiếu đến những gì 'malloc()' trả về. Bộ nhớ này chưa bao giờ được sử dụng và sẽ không bao giờ được sử dụng trong thời gian trực tiếp của chương trình. – alk

+0

'sizeof (char)' là '1' là defintion. Đúc kết quả của 'malloc/calloc/realloc' không cần thiết trong C hoặc không được khuyến nghị: http://stackoverflow.com/a/605858/694576 – alk

+0

Nhờ tất cả mọi người đã trả lời đó là một trợ giúp tuyệt vời – user2826534