Hỏi về cách free cho struct array

xin chào mọi người,
mình đang trăn trở làm cách nào để free 1 struct của mình mà lăn lộn khắp stac
koverlow ko tìm được câu trả lời mong muốn, hi vọng các bạn có thể giúp

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

 typedef struct Artikel //object
	{
	  	
	  	char Artikelsname[50]; // mota object
		char ArtikelsNummer[10]; // ma san pham
		char Anzahl[100];
	}Artikel;

int main()
{	

	struct Artikel *addArtikel;

	printf("Anzahl der zu eingebene Artikel\n");
	char z[128];
	int a;
	fgets(z,sizeof(z),stdin);
	a = atoi(z);
	
	
	addArtikel = malloc(a*sizeof(Artikel)); // addArtikel ist verdammt pointer passss auf!!!!! und 
	int i;
	for (i = 0; i< a;i++)
	{
	printf("Name des Artikels eingeben\n");
	fgets(addArtikel[i].Artikelsname,128,stdin);
	printf("ArtikelsNummer eingeben\n");
	fgets(addArtikel[i].ArtikelsNummer,128,stdin);
	printf("Anzahl eingeben\n");
	fgets(addArtikel[i].Anzahl,128,stdin);
	}
	for(i=0;i<a;i++)
	{printf("ArtikelsName ist %s mit ArtikelsNummer ist %s und mit der Anzahl %s",addArtikel[i].Artikelsname,addArtikel[i].ArtikelsNummer,addArtikel[i].Anzahl);}
	//free(addArtikel[2]->Artikelsname); Minh can giup cho nay :(


	
	



return 0;
}

Code này bạn lấy đại của người khác về test à :v Toàn tiếng Đức (đoán vậy) không, cũng khó mà hiểu được code này làm cái gì :expressionless: Nhưng mà quan trọng là bạn cấp cái gì thì mới được free cái đó. Trong trường hợp này, bạn đã cấp phát cho addArtikel thì free(addArtikel) mới được nhé.
Mục đích của bạn khi giải phóng cho 1 trường của 1 phần tử trong đó là gì vậy?
Rồi nhớ đọc thêm cách post code, giống ‘bỏ con giữa chợ’, post lên là xong, thấy xấu, khó nhìn chứ không tìm cách sửa :expressionless:

1 Like

Artikelname không free được do nó ko phải là vùng nhớ tạo ra từ malloc.

cảm ơn bạn đã nhắc nhở,
code này tự mình viết, mình đang học ở bên Đức, project là làm 1 phần mềm quản lý kho hàng, giờ mình đã tạo ra nhiều struct rồi muốn giải phóng 1 trong số cái đó thì làm thế nào hả bạn?

Chỉ có thể free 1 con trỏ thôi. Để rút lại thì dùng realloc.

1 Like

bạn tạo struct, trong struct chỉ là bộ nhớ tĩnh, bạn tạo 1 con trỏ cho struct này và cấp phát cho nó n phần tử, bạn muốn free thì cứ việc free cái vùng bạn muốn free, ví dụ như free addAtikel[2]. Tuy nhiên cách làm này tiềm ẩn lỗi, nếu cuối cùng bạn muốn giải phóng hoàn toàn mà dùng free(addAtikel) thì sẽ bị crash vì vùng addAtikel[2] đã đc thu hồi, không do bạn quản lý nữa.
Trong code bạn đưa ra bạn đang cố gắng giải phóng 1 vùng nhớ tỉnh, addAtike[2]-> name, cú pháp này sai vì thằng addAtike[2] không phải là 1 con trỏ, nó là 1 vùng nhớ, đúng là addAtike[2].name; vùng nhớ tỉnh nằm trong stack do hệ điều hành quản lý nên ko phải free nó, nếu cố free sẽ lại bị lỗi.

Nghe này, bạn xin một cái hộp để chứa đồ* (tương tự như khi gọi malloc để xin cấp phát vùng nhớ) thì nó là cố định rồi, bạn sẽ bắt đầu sử dụng nó để chứa đồ (tương tự việc bạn gán giá trị vào trong đó), và việc bạn giải phóng cho cho 1 trường của 1 phần tử struct đồng nghĩa với việc bạn đang muốn xẻo đi một phần của gói hàng và cái hộp và điều đó là không thể vì bạn có dao chuyên dụng (tương tự với việc không có biện pháp gì để giải phóng nó cả) :smiley:

Bạn chỉ có thể:

  • Xin một cái hộp khác nhỏ hơn và chuyển những món đồ cần thiết qua đấy (tương tự: realloc và memcpy)
  • Bỏ luôn món đồ không cần thiết ra (tương tự việc cho phần đó trỏ tới NULL)

Tóm lại: [quote=“rogp10, post:3, topic:62286, full:true”]
Artikelname không free được do nó ko phải là vùng nhớ tạo ra từ malloc.
[/quote]

Bạn mượn người ta cái hộp thì hãy trả lại cái hộp, người ta không chấp nhận “trả góp” đâu.

chào bạn,
cảm ơn vì kiến thức bổ ích, tuy nhiên mình đã thử cú pháp free(addartikel[2]) nhưng nó báo lỗi abortion. nếu giả sử free đc cái addartikel[2] đó thì mấy phần tử đi theo nó cũng đc free luon hả bạn?

giờ mình muốn trả hộp nó cũng k đc cơ :frowning:

Gọi free con trỏ nào thì chỉ có vùng nhớ (con trỏ qua malloc sẽ ứng với vùng nhớ và không qua malloc mà free là chít - lưu ý) đó được lấy lại mem thôi, còn nếu trong vùng đó có những con trỏ khác chưa free thì những vùng nhớ đó còn y nguyên.

Câu này có hình minh họa sẽ dễ hiểu hơn :slight_smile:

trước giờ mình quản lý struct đều bằng con trỏ, ở đây đầu tiên bạn cấp phát 1 con trỏ cấp 2 quản lý n con trỏ trỏ tới struct của bạn, sau đó cấp phát bộ nhớ cho n con trỏ đó, hoàn toàn tương tự như cấp phát mảng 2 chiều. Sau đó bạn muốn giải phóng thằng nào chỉ đơn giản free(arrP[i]); arrP[i] = null;
làm gì làm, sau đó giải phóng toàn bộ n con trỏ, chạy vòng for thằng nào khác null thì free, cuối cùng thì free con trỏ bậc 2.

chào bạn,
mình có sử dụng con trỏ thứ 2 và cấp phát bộ nhớ 1 lần nữa, hôm kia mình cũng đã thử qua nó, kì diệu là nó xoá đc được 1 phần tử của 1 trường chứ ko phải cả trường(vd addArtikel[2]) như mình mong muốn. Mà nó cũng ko hẳn là xoá, lúc mình output ra nó có kí hiệu như kiểu chữ TQ :)))

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?