THỰC HÀNH:
Tôi hiện đang giảng dạy một người bạn của tôi những khái niệm cơ bản của C - và đến với điều này rất đơn giản và thẳng về phía trước (tôi hy vọng như vậy) mã ví dụ mà về cơ bản giải thích tất cả mọi thứ. Không muốn giấu nó khỏi các bạn! :)
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* function header definitions */
char* getString(); //<- with malloc (good practice)
char * getStringNoMalloc(); //<- without malloc (fails! don't do this!)
void getStringCallByRef(char* reference); //<- callbyref (good practice)
/* the main */
int main(int argc, char*argv[]) {
//######### calling with malloc
char * a = getString();
printf("MALLOC### a = %s \n", a);
free(a);
//######### calling without malloc
char * b = getStringNoMalloc();
printf("NO MALLOC### b = %s \n", b); //this doesnt work, question to yourself: WHY?
//HINT: the warning says that a local reference is returned. ??!
//NO free here!
//######### call-by-reference
char c[100];
getStringCallByRef(c);
printf("CALLBYREF ### c = %s \n", c);
return 0;
}
//WITH malloc
char* getString() {
char * string;
string = malloc(sizeof(char)*100);
strcat(string, "bla");
strcat(string, "/");
strcat(string, "blub");
printf("string : '%s'\n", string);
return string;
}
//WITHOUT malloc (watch how it does not work this time)
char* getStringNoMalloc() {
char string[100] = {};
strcat(string, "bla");
strcat(string, "/");
strcat(string, "blub");
//INSIDE this function "string" is OK
printf("string : '%s'\n", string);
return string; //but after returning.. it is NULL? :)
}
// ..and the call-by-reference way to do it (prefered)
void getStringCallByRef(char* reference) {
strcat(reference, "bla");
strcat(reference, "/");
strcat(reference, "blub");
//INSIDE this function "string" is OK
printf("string : '%s'\n", reference);
//OUTSIDE it is also OK because we hand over a reference defined in MAIN
// and not defined in this scope (local), which is destroyed after the function finished
}
Khi biên dịch nó, bạn sẽ có được [dự định] cảnh báo:
[email protected]:~$ gcc -o example.o example.c
example.c: In function ‘getStringNoMalloc’:
example.c:58:16: warning: function returns address of local variable [-Wreturn-local-addr]
return string; //but after returning.. it is NULL? :)
^~~~~~
... về cơ bản những gì chúng ta đang thảo luận ở đây!
chạy ví dụ của tôi mang lại kết quả này:
[email protected]:~$ ./example.o
string : 'bla/blub'
MALLOC### a = bla/blub
string : 'bla/blub'
NO MALLOC### b = (null)
string : 'bla/blub'
CALLBYREF ### c = bla/blub
LÝ THUYẾT:
này đã được trả lời rất độc đáo bởi @phoxis tài khoản. Về cơ bản hãy suy nghĩ theo cách này: Mọi thứ ở giữa { và } là phạm vi địa phương, do đó, C-Standard là "không xác định" bên ngoài. Bằng cách sử dụng malloc bạn lấy bộ nhớ từ HEAP (phạm vi chương trình) chứ không phải từ STACK (phạm vi chức năng) - do đó có thể nhìn thấy từ bên ngoài. Cách chính xác thứ hai để thực hiện là gọi theo tham chiếu. Ở đây bạn định nghĩa var bên trong parent-scope, do đó nó đang sử dụng STACK (vì phạm vi cha là main()).
TÓM TẮT:
3 cách để làm điều đó, Một trong số đó sai. C là loại vụng về để chỉ có một hàm trả về một chuỗi có kích thước động. Hoặc bạn phải malloc và sau đó giải phóng nó, hoặc bạn phải gọi theo tham chiếu. Hoặc sử dụng C++;)
thể trùng lặp của [C Cảnh báo: Chức năng trả về địa chỉ của biến cục bộ] (http://stackoverflow.com/questions/6897914/c-warning-function-returns-address-of-local-variable) – netcoder
Khi bạn viết câu hỏi của bạn, nó gợi ý một vài bản sao dựa trên nó. Có lẽ bạn nên kiểm tra chúng. – netcoder
tôi nghĩ rằng nó có thể hữu ích http://stackoverflow.com/a/6897993 –