cuốn sách gpt4 ai đã làm

Sqlite3 và pthread, miễn phí gấp đôi hoặc bị hỏng (hết)

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 05:41:33 26 4
mua khóa gpt4 Nike

Tôi cố gắng tạo một luồng kết nối với cơ sở dữ liệu, lấy một số dữ liệu từ đó và in nó ra bảng điều khiển. Vấn đề là khi chủ đề này hoàn thành, nó sẽ đưa ra một ngoại lệ:

Nhân đôi miễn phí hoặc bị hỏng (ra)Hủy bỏ (kết xuất lõi)

Tôi đã thử sử dụng sqlite3 và pthread, nhưng hai người này không thực sự là bạn bè.

Tôi đoán vậy, nhưng tôi không chắc liệu vấn đề có xuất phát từ lớp cơ sở dữ liệu hay không.

Có ai biết điều gì đang tạo ra ngoại lệ không? Đây là mã của tôi:liên kết

Lớp cơ sở dữ liệu:

Cơ sở dữ liệu lớp {
private:
sqlite3 *db;
int tĩnh CallBack(void *data, int argc, char **argv, char **azColName)
{
chỉ số int = 0;
char** dataToReturn = char mới*[1000];

trong khi (dataToReturn[chỉ mục])
{
chỉ mục++;
}

cho (int i = chỉ mục; i < argc + chỉ mục; i++)
{
dataToReturn[i] = (char *)malloc(sizeof(char) * sizeof(argv[i - index]));
strcpy((dataToReturn)[i], argv[i - index]);
}

return 0;
}

public:
char **Chọn()
{
char *zErrMsg = 0;
int rc;

rc = sqlite3_open("test.db", &db);

nếu(rc)
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(1);
}
khác
{
fprintf(stderr, "Đã mở cơ sở dữ liệu thành công\n");
}
dữ liệu char **;

int rc2 = sqlite3_exec(db, "CHỌN * TỪ SHARED_FILE", Gọi lại, dữ liệu, &zErrMsg);

nếu (rc2 != SQLITE_OK)
{
sqlite3_free(zErrMsg);
exit(2);
}

sqlite3_close(db);
trả về dữ liệu;
}

Chức năng chủ đề:

khoảng trống tĩnh FuncioForThread()
{
printf("bắt đầu");

cơ sở dữ liệu tự động = Cơ sở dữ liệu mới();
char** returnData = cơ sở dữ liệu->Chọn();

printf("thứ gì đó từ db: %s \n", returnData[0]);
printf("dừng");
}

khoảng trống tĩnh *threadd(void *arg)
{
pthread_detach(pthread_self());
fflush(stdout);

FuncioForThread();
}

Chức năng chính:

int main()
{
chủ đề pthread_t;
char arg[100] = "kiểm tra";
pthread_create(&thread, NULL, &threadd, arg);

trong khi(1);
}

câu trả lời hay nhất

Bạn đang hủy tham chiếu((char **)dữ liệu)[chỉ mục]được chuyển đếnGọi lạicủadata, nhưng giá trị của nó được chuyểnsqlite3_execCuộc gọi lại từSelectTRONGdatađược truyền lại. Select TRONG data Đã được giao cho:

char **data = (char **)malloc(0);

Không được phép tham chiếu con trỏ được phân bổ có độ dài bằng 0. Cũng lưu ý rằng kích thước bằng không malloc Hành vi của được xác định theo cách triển khai, do đó nên tránh (giống như trong C++ malloc trong mọi trường hợp được ưu tiên hơn new Như nhau).

Sau khi chỉnh sửa:

Hiện nay data từ Select được trả lại, nhưng không bao giờ được viết vào nó, nhưng sau đó trong

Dereference trong
returnData[0]

hiện hữuChức năngForThreadở giữa. Đây là hành vi không xác định.

此外,sizeof(argv[i - chỉ mục]) sẽ không trở lại argv[i - chỉ mục] Độ dài của chuỗi được chỉ tới. Nó sẽ trả về kích thước của kiểu con trỏ. Do đó, phân bổ của bạn có thể quá nhỏ, lại là hành vi không xác định. sử dụng std::stlen Lấy độ dài của chuỗi kết thúc bằng 0.

Sau đó con trỏargv[i - chỉ mục]Nó cũng có thể làNULLđể chỉ ra hàng trở lạiNULLgiá trị (xemtài liệu của sqlite3_exec). Trong trường hợp này tiến hành từ strcpy Hoạt động cũng sẽ là hành vi không xác định.

循环trong khi (dataToReturn[chỉ mục])sẽ dẫn đến hành vi không xác định vìdữ liệuToReturnMảng được phân bổ nhưng các phần tử của nó không bao giờ được đặt. Ngay cả khi giá trị được đặt, hãy lưu ý rằng chuỗi kiểu C khi và chỉ khi dữ liệuToReturn[chỉ mục] Điều kiện chỉ được đáp ứng khi chiều dài nhọn bằng 0. Nếu không có chuỗi nào tồn tại trong phạm vi được phân bổ thì hành vi đó lại không được xác định.

Bạn cũng bị rò rỉ bộ nhớ vì bạn không bao giờgiải phóngbất kìmallocdữ liệu và bởi vìdữ liệuToReturnbị loại bỏ vào cuối mỗi cuộc gọi CallBack, vì vậy nó không hữu ích lắm.

Không có lý do chính đáng nào để sử dụng tất cả các cấu trúc kiểu C này. sử dụng new thay thế malloc,sử dụng std::chuỗistd::vector thay thế ký tự Mảng, sử dụng std::coutstd::cerr thay thế printffprintf(stcerr, ...,std::chủ đề thay thế pthread. Điểm duy nhất cần xem xét là ranh giới giao diện của thư viện C.

Về c++ - Sqlite3 và pthread, trống gấp đôi hoặc bị hỏng (ngoài), chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/53964158/

26 4 0
không gian vũ trụ
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress