Lỗi khi trả về giá trị của con trỏ thông qua hàm (segmentation fault core dumped) trong C++
Hôm nay mình mới gặp một lỗi cơ bản trong lập trình C như này, chia sẻ lên đây để mọi người cùng thảo luận.
Mình có viết một đoạn code để tính toán giá trị và trả về con trỏ như sau:
#include <stdio.h>
#include <stdlib.h>
typedef struct data_feature{
int dim;
double *data;
}Feature;
Feature* func1(){
Feature datatype;
Feature *ptr = &datatype;
ptr->dim = 2;
ptr->data = (double*)calloc(2,sizeof(double));
ptr->data[0] = 0;
ptr->data[1] = 1;
return ptr;
}
int main(){
Feature *sp =NULL;
sp = func1();
for(int i =0; i<2; i++){
printf("
data");
printf("
value %d: %lf",i,sp->data[i]);
}
}
Với đoạn code trên mình nhận được lỗi segmentation fault khi lấy giá trị sp->data[i] trong hàm main.
Theo lý giải của mình thì vấn đề nằm ở chỗ trong hàm func1 khi con trỏ ptr trỏ đến biến data, nhưng sau khi kết thúc hàm thì biết data được giải phóng do đó giá trị trả về của hàm sẽ là một con trỏ mà trỏ đến vùng nhớ vô định.
Với lý giải như trên mình đã thay đổi bằng cách truyền tham chiếu vào hàm func1 như sau: func1(Feature &datatype). Với cách này mình thay đổi trực tiếp datatype được truyền vào. Và do đó mình không còn bị segmentation fault core dumped nữa.
Theo các bạn mình lý giải và giải quyết như trên có ổn không? bạn nào có gặp phải những lỗi tương tự hoặc biết những lỗi tương tự trong việc trả về giá trị con trỏ thì chia sẻ mọi người cùng tham khảo nhé.
Đoạn code chạy đúng:
typedef struct data_feature{
int dim;
double *data;
}Feature;
void func1(Feature &datatype){
datatype.dim = 2;
datatype.data = (double*)calloc(2,sizeof(double));
datatype.data[0] = 0;
datatype.data[1] = 1;
}
int main(){
Feature sp;
func1(sp);
for(int i =0; i<2; i++){
printf("
data");
printf("
value %d: %lf",i,sp.data[i]);
}
}
C++ nha vì C không cho truyền tham chiếu.
datatype sau hàm func1 sẽ bị giải phóng, nhưng biến ptr bạn vẫn trỏ đến địa chỉ datatype, nên khi ở trong hàm main
sp->data[i]
thì sp đang trỏ đến 1 vùng nhớ đã bị giải phóng nên segmentation fault thôi.Hàm dưới thì hoàn toàn ok
Uhm mình cũng hiểu là như thế. Mình mới search thì còn một số giải pháp khác:
stackoverflow.com
Returning a struct pointer
theo đó có thể viết lại hàm func1 như sau:
thế cũng được nhưng thằng dùng hàm func1() thì phải đi giải phóng ptr nếu không sẽ leak memory